Project 1 Approach
For single resolution images, I bruteforce search for the correct offset within a 128x128 box. In an early approach, the similarity score is determined by the dot product between two normalized images, but it failed to align emir. So I handwrote a sobel filter using scipy.signal.convolve since high level functions are prohibited.
For high-resolution images, I scale the image down to about 1/8 and apply the same search algorithm within the 128x128 box. After that, the algorithm progresses up each step by a factor of 2, aligning the 1/4, 1/2, and 1/1 images successively. Note that you only have to search within a 2x2 box after the first alignment, which is a dramatic speedup.
Cropping
I attempted to use sobel filter and a loop to count the number of disrupting changes in rows and columns. I took the dot product between each row and its reverse, a low number signifies low self-similarity. It eventually didn't work out so I resorted to a fixed percentage.
Color Remapping
Instead of doing np.dstack, you can multiply each color channel by a vector of 3 color weights. You do that for all three channels and then add the results together.