Colorizing Prokudin-Gorskii Photography Collection
The paper’s aim is colorizing Prokudin-Gorskii photography collection. You can find source code in: https://github.com/ilgazhilal/Prokudin-Gorskii-photo-collection-using-OpenCV
The collection is very large and photos which are in collection on various themes. Photos contain people, religious architecture, industry, views of different places etc [1]. Photographs look like gray but they have 3 color channels. Those are red, green and blue. These channels’ sequence is not classic order. It means channels’ order is blue, green and red. Images should be splitted three parts and the parts should be assign the rgb channels. The photo should be colored by stacking the channels [1].
First of all, I wanted to see unaligned results. Because I couldn’t imagine how images should be looked like. I splitted images according to height/3. And I assigned bgr channels. When the channels were merged, result images should be unaligned results. According to unaligned results, I had an idea about how images should look.
image_name='00087u.jpg'
img=cv2.imread(image_name)
gimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#I turned gray for shape method. I only need width and height.
gimg=np.asarray(gimg) #I wanted to use like an array for cropping and the other calculations
print(img.shape)
print(gimg.shape)
plt.imshow(gimg)
There are some unailgned results without cropping.
I cropped images to look neat. For cropping, I chose the numbers after a few tries.
y=30
x=30 #I assigned this randomly.
height,width=gimg.shape
gimg = gimg[y:height-y, x:width-x] #This is a classical cropping method
height,width=gimg.shape
print(height,width)
plt.imshow(gimg)
The images have three parts. Before aligning, I split these parts.
rgb_height=int(height/3)#I divided to image 3 different parts. int function is used for getting rid of comma
blue=gimg[0:rgb_height,:] #First part is blue
green=gimg[rgb_height:2*rgb_height,:] #second part is green
red=gimg[2*rgb_height:3*rgb_height,:]#third part is red. It is not normal sequence so I did not use split function.
plt.figure()
plt.imshow(blue)
plt.figure()
plt.imshow(green)
plt.figure()
plt.imshow(red)
I stacked these channels into one.
For aligning images part, I choosed NCC. NCC standardizes the picture being moved, and afterward takes the internal result of that picture and the one it is being contrasted with as a vector. The bigger this worth, the closer the two pictures are, and consequently, the better the match [2]. NCC has its own formula. I applied this formula in my NCC method. I think aligning method more important than NCC’s own method. Also I use lots of methods which are already in libraries like numpy. These methods are linspace(), roll(), square(), sum(), sqrt() and mean(). Math functions were used for NCC. I gave two images to NCC method but in aligning method designed to travel all pixels in images. So I also used in this part roll() method and linspace() method. Linspace() function takes x and y coordinates and keeps producing number between this interval. I gave -30 for starting, the method added 1 until 30 for end. Roll() method used for shifting actually. With NCC, I had new variables and I had to match them with the old variables along given axis.
def ncc(a1,a2):
a1=a1-a1.mean()
a2=a2-a2.mean()
return np.sum(((a1/np.sqrt(np.sum(np.square(a1)))) * (a2/np.sqrt(np.sum(np.square(a2))))))
def alignNCC(a1, allign_a1,travel):
min_limit = -1 #I assigned that for control. It is a min limit for loop.
value=np.linspace(-travel,travel,travel+1,dtype=int) #This section for travelling all pixels. linspace() is a method in numpy library.
#I give x and y coordinates and it is keep producing number between this coordinates.
for x in value:
for y in value:
ncc_value = ncc(a1,np.roll(allign_a1,[x,y],axis=(0,1)))
if ncc_value > min_limit:
min_limit = ncc_value
output = [x,y]
return output
greenBlue = alignNCC(blue,green,30)
redBlue = alignNCC(blue,red,30)
print("GreenNCC:",greenBlue)
print("RedNCC:", redBlue)
allignGreen=np.roll(green,greenBlue,axis=(0,1)) #This is for rolling the images green to value in given axis.
allignRed=np.roll(red,redBlue,axis=(0,1))
allignPhoto_ncc = (np.dstack((allignRed,allignGreen,blue))).astype(np.uint8)
When I aligned images with NCC, I liked the results. I thought results are fine but they can be more than fine. So I cropped images’ edges -black borders-. I used matplotlib for plotting. I did not save the images.
An Aligned Result Using NCC Without Cropping
For cropping I chose two coordinates, these were x and y. I choose them randomly. I am not sure, this is the correct way but results are as required. I assumed size of images are MxM when images divided by three. So, I cropped equal amount from top, down, left and right. After cropping, the images looked much better.
Aligned Results Using NCC With Cropping
Consequently, my idea is images which are not very complicated give good results. Also image metrics are very important for aligning. Without NCC, images looked like shifted. It means they can not stack properly. Also, with black borders aligned images are similar to unaligned images.
References
1) Internet: Anonim. (nd) About the Prokudin-Gorskii Collection. Web: https://www.loc.gov/ pictures/collection/prok/
2)Internet: Chen E.(nd) Image Alignment. Web: http://www.emileechen.com/projects/image alignment/