SIFT (Scale Invariant Feature Transform) is one of the underlying concepts in Structure from Motion photogrammetry, which plays a large part in my Masters research. To better understand how the process works I am working through the process manually, calculating all of the intermediate steps along the way.
The first (of 4) phases of SIFT is Scale-space feature extrema detection (Lowe, 2004). In this phase the features to be compared at later stages of analysis are isolated from the rest of the image data. Since SIFT requires that features be identifiable across all image scales, they must be first created at multiple scales for comparison. I’ll get into this later, but first we have to explore exactly how features can be isolated at any given scale from images that may be taken at varying times of day, with different exposure settings or any other factors that may impact the color or brightness of an image.
Here is an example of how the difference of Gaussians method helps correct for changes in lighting. I’ve taken one photo, then artificially increased the exposure on it and compared the difference of Gaussian images between the original and the over-exposed one.
As you can see, the normal exposure shows a lot more details, which is to be expected as more detail is shown in the original photo than in the comparatively over-exposed image. However by multiplying the normal exposure DoG image with the inverse of the over-exposed one you get common points that exist between the two. Since there are still quite a number of coincident points, the illumination has little impact on SIFT’s ability to find common points between two images with different lighting parameters.
Here is the Python code I used to accomplish this, I just copied my whole utility into here for both creating a new difference of Gaussian image and comparing two different ones:
import cv2 import numpy as np def DoG(): fn = raw_input("Enter image file name and path: ") fn_no_ext = fn.split('.') outputFile = fn_no_ext+'DoG.jpg' #read the input file img = cv2.imread(str(fn)) #run a 5x5 gaussian blur then a 3x3 gaussian blr blur5 = cv2.GaussianBlur(img,(5,5),0) blur3 = cv2.GaussianBlur(img,(3,3),0) #write the results of the previous step to new files cv2.imwrite(fn_no_ext+'3x3.jpg', blur3) cv2.imwrite(fn_no_ext+'5x5.jpg', blur5) DoGim = blur5 - blur3 cv2.imwrite(outputFile, DoGim) def compareImages(): input1 = raw_input('enter the first image to be compared: ') input2 = raw_input('enter the second image to be compared: ') outFile = raw_input('enter the filename of the desired output: ') in1 = cv2.imread(input1) in2 = cv2.imread(input2) output1 = in2 * -1*in1 cv2.imwrite(outFile+'.jpg', output1) print "Welcome to the Difference of Gaussian Image creation utility." actionSelection = raw_input("If you would like to compare two images type \"Compare\", if you want to calculate a new set Difference of Gaussian image type \"New\": \n").lower() if actionSelection == "new": DoG() elif actionSelection == "compare": compareImages() else: print "Not a valid selection."