OpenCV: How to implement "Keystone Correction"?
I want to take an image that is looking at the rectangle from the bottom (creating a trapezoid) and change it to the original rectangle. For example, imagine you were on the ground photographing a skyscraper. I want to use this data to find out what the side of a skyscraper looks like. How can i do this?
Keystone correction usually refers to an offset projector, but that's not really what's going on. My original image is already messed up just like an offset projector would. I need to get it straight.
Thanks for any help. If it's important, I'm using the Java version of OpenCV, but I'm happy with any answers; I'm sure it's easy to do this in java from any other language.
Edit: I want to do what is shown for Notre Dame on this page: https://en.wikipedia.org/wiki/Perspective_control
source to share
This is called homography. You need to know the angles of the trapezoid and then calculate the homography matrix using the findHomography function and then use the warpPerspective function to generate the corrected image. I wrote a simple python program for you to play around and provide an image of the result so you know what it does and see what you say.
code
import cv2
import numpy as np
import cv
pSrc = [( 98,67),( 331 , 75),( 415 , 469),( 27 , 466)]
pDst = [( 27,67),( 415 , 75),( 415 , 469),( 27 , 466)]
def srcMouse(event, x, y, flags,params):
global pSrc
if event == cv.CV_EVENT_LBUTTONDOWN:
if len(pSrc) >=4:
pSrc=[]
pSrc.append((x,y))
print np.array(pSrc,dtype=np.float32)
def dstMouse(event, x, y, flags,params):
global pDst
if event == cv.CV_EVENT_LBUTTONDOWN:
if len(pDst) >=4:
pDst=[]
pDst.append((x,y))
cv2.namedWindow('src')
cv.SetMouseCallback('src', srcMouse, 0)
cv2.namedWindow('dst')
cv.SetMouseCallback('dst', dstMouse, 0)
im = cv2.imread('c:/data/notre.jpg')
dst = np.zeros(im.shape,dtype=np.uint8)
while(1):
imD = im.copy()
dstD = dst.copy()
for p in pSrc:
cv2.circle(imD,p,2,(255,0,0),-1)
for p in pDst:
cv2.circle(dstD,p,2,(255,0,0),-1)
if len(pSrc)==4 and len(pDst)==4:
H = cv2.findHomography(np.array(pSrc,dtype=np.float32),np.array(pDst,dtype=np.float32),cv2.LMEDS)
dstD=cv2.warpPerspective(imD,H[0],(dstD.shape[1],dstD.shape[0]))
cv2.imshow('src',imD)
cv2.imshow('dst',dstD)
if cv2.waitKey(1) ==27:
exit(0)
source to share