Image Stitching

BlitzPlus Forums/BlitzPlus Programming/Image Stitching

Hello all, I was wondering if anyone could help me figure out a way to compare two pieces of two images that have overlap. I want to check for similarities in parts of the image, so that I can position them properly to each other. I thought about just checking the farthest right rows of pixels against the farthest left rows of the second image, but i'm not sure where to begin with it all as far as coding goes. Is there a way to store that specific pixel info, and if I did store it, how would I compare them? Thanks!

Well, your problem needs a specific solution, but this sample code may help.

I slapped it together. It's not fast AT ALL, but it looks like it could work with some modifications and speed improvements. I didn't have time to check into why it places the box where it does.

It compares a 2 pixel wide strip from the left side of the smaller image with every vertical stip of the larger image.

;setup code
Graphics 1024, 768

image1 = CreateImage(400, 300)
SetBuffer ImageBuffer(image1)
ClsColor 0, 255, 0
Cls
Color 255, 0, 0
Rect 20, 20, 300, 200, 0
Rect 21, 21, 298, 198, 0

image2 = CreateImage(300, 200)
SetBuffer ImageBuffer(image2)
Color 255, 0, 0
Rect 0, 0, 300, 200

SetBuffer FrontBuffer()
ClsColor 0, 0, 255
Cls
DrawBlock image1, 50, 50
DrawBlock image2, 550, 50
Text 75, 25, "Image 1"
Text 575, 25, "Image 2"

;stitching code
Dim StitchCoord(1) ;offset values for image 2, 0=col, 1=row
result = Stitch(image1, image2)
If result = -1 Then RuntimeError("One of the image handles isn't valid!")
If result = -2 Then RuntimeError("Images are completely incompatible.")

Text 75, 425, "Stitched at " + StitchCoord(0) + ", " + StitchCoord(1)
DrawBlock image1, 50, 450
DrawBlock image2, 50+StitchCoord(0), 450+StitchCoord(1)

Flip

WaitKey()
End

Function Stitch(image1, image2)
	;this function only compares with the entire height
	;of the smaller image always within the boundaries of the larger image
	If image1 = 0 Or image2 = 0 Then Return -1
	i1h = ImageHeight(image1)
	i2h = ImageHeight(image2)
	If i2h > i1h ;make larger image the first image
		tempimage = image1
		image1 = image2
		image2 = tempimage
	EndIf
	i1h = ImageHeight(image1)	;just in case they switched
	i2h = ImageHeight(image2)	;just in case they switched
	i1w = ImageWidth(image1)
	i2w = ImageWidth(image2)
	
	bank1 = CreateBank(i2h*2)				;create a bank the height of image2 * 2 pixel width
	bank2 = CreateBank((i1h-i2h) * (i1w-1))	;create a bank to store all of the percentages for each possible location
	
	;compare the images one (double pixel width) strip at a time from right to left of larger image
	For column = i1w-2 To 0 Step -1
		For row = 0 To i1h-i2h-1
			For c = 0 To 1
				For r = 0 To i2h-1
					pix1 = ReadPixel(column+c, row+r, ImageBuffer(image1))
					pix2 = ReadPixel(i2w-1+c, r, ImageBuffer(image2))
					
					red1 = (pix1 Shl 8) Shr 24
					green1 = (pix1 Shl 16) Shr 24
					blue1 = (pix1 Shl 24) Shr 24
					
					red2 = (pix2 Shl 8) Shr 24
					green2 = (pix2 Shl 16) Shr 24
					blue2 = (pix2 Shl 24) Shr 24
					
					redperc = ((255-(Abs(red1 - red2)))/255.0)*100
					greenperc = ((255-(Abs(green1 - green2)))/255.0)*100
					blueperc = ((255-(Abs(blue1 - blue2)))/255.0)*100
					
					pixelperc = (redperc + greenperc + blueperc)/3.0
					PokeByte bank1, c*i2h+r, pixelperc
				Next
			Next
			;create a total percentage value for the entire strip comparison
			stripPerc = 0
			For iter = 0 To i2h*2-1
				stripPerc = stripPerc + PeekByte(bank1, iter)
			Next
			stripPerc = stripPerc/(i2h*2.0)
			;store that percentage into bank2
			PokeByte bank2, column*(i1h-i2h)+row, stripPerc
			If stripPerc = 100 Then Exit
		Next
		If stripPerc = 100 Then Exit
	Next
	
	;now find the best comparison location found in bank2
	For iter = 0 To (i1h-i2h) * (i1w-1)
		If PeekByte(bank2, iter) > bestperc
			bestperc = PeekByte(bank2, iter)
			StitchCoord(0) = Floor(iter/(i1h-i2h))
			StitchCoord(1) = iter Mod (i1h-i2h)
		EndIf
		If bestperc = 100 Then Exit	;exit loop if we find a perfect match
	Next							;otherwise continue looking for best match
	FreeBank bank1
	FreeBank bank2
	If bestperc = 0 Then Return -2
End Function

;end of file


Thank you for the example! I'll give it a go when I get home and see if I can pick it apart/understand it. Thanks again!