7

I have only just started experimenting with OpenCV a little bit. I have a setup of an LCD with a static position, and I'd like to extract what is being displayed on the screen from the image. I've seen the chessboard pattern used for calibrating a camera, but it seems like that is used to undistort the image, which isn't totally what I want to do.

I was thinking I'd display the chessboard on the LCD and then figure out the transformations needed to convert the image of the LCD into the ideal view of the chessboard directly overhead and cropped. Then I would store the transformations, change what the LCD is displaying, take a picture, perform the same transformations, and get the ideal view of what was now being displayed.

I'm wondering if that sounds like a good idea? Is there a simpler way to achieve what I'm trying to do? And any tips on the functions I should be using to figure out the transformations, perform them, store them (maybe just keep the transform matrices in memory or write them to file), etc?

karlphillip
  • 87,606
  • 33
  • 227
  • 395
kevin.key
  • 275
  • 1
  • 3
  • 8
  • If you shared the image you are using for testing would help a lot. The chessboard pattern is used for camera calibration. That aims to remove the distortion caused by the lens of the camera. Once you have the values of for the calibration, you can hard code those values into a procedure in your application so it does the *calibration* automatically. – karlphillip Oct 26 '11 at 16:53
  • I don't have a picture, but imagine drawing a chessboard in photoshop. Then transform it so it's rotated and viewed from a slight perspective. I'd like to remove the camera distortion with the chessboard calibration, but I'm also wondering if I can use the chessboard to figure out the transforms required to undo the rotate and perspective. – kevin.key Oct 26 '11 at 18:03
  • I imagine this question has been answered by now, either by one of the posts below or by a different approach you found. – karlphillip Jul 07 '12 at 01:17

2 Answers2

18

I'm not sure I understood correctly everything you are trying to do, but bear with me.

Some cameras have lenses that cause a little distortion to the image, and for this purpose OpenCV offers methods to aid in the camera calibration process.

Practically speaking, if you want to write an application that will automatically correct the distortion in the image, first, you need to discover what are the magical values that need to be used to undo this effect. These values come from a proper calibration procedure.

The chessboard image is used together with an application to calibrate the camera. So, after you have an image of the chessboard taken by the camera device, pass this image to the calibration app. The app will identify the corners of the squares and compute the values of the distortion and return the magical values you need to use to counter the distortion effect. At this point, you are interested in 2 variables returned by calibrateCamera(): they are cameraMatrix and distCoeffs. Print them, and write the data on a piece of paper.

At the end, the system you are developing needs to have a function/method to undistort the image, where these 2 variables will be hard coded inside the function, followed by a call to cv::undistort() (if you are using the C++ API of OpenCV):

cv::Mat undistorted;
cv::undistort(image, undistorted, cameraMatrix, distCoeffs);

and that's it.

Detecting rotation automatically might be a bit tricky, but the first thing to do is find the coordinates of the object you are interested in. But if the camera is in a fixed position, this is going to be easy.

For more info on perspective change and rotation with OpenCV, I suggest taking a look at these other questions:

Executing cv::warpPerspective for a fake deskewing on a set of cv::Point

Affine Transform, Simple Rotation and Scaling or something else entirely?

Rotate cv::Mat using cv::warpAffine offsets destination image

Community
  • 1
  • 1
karlphillip
  • 87,606
  • 33
  • 227
  • 395
  • Well, I updated the answer with some links that you might find interesting and they may help you achieve what you want. – karlphillip Oct 26 '11 at 19:38
  • Not exactly. After doing an undistort the image would still look like this: [link](http://www.thechesszone.com/images/chess-boards-leather/TCZ_204GN_1.jpg) It won't be that extreme of an angle, but that's what I mean by rotated and at a perspective. So then I was thinking with the corners obtained by the function: `cvFindChessboardCorners`. The transformations could be calculated to get the chess board directly overhead: [link](http://images.bibliocad.com/library/image/00020000/0000/chess-board_20342.gif) . Then those same transformations could be used on subsequent images. – kevin.key Oct 26 '11 at 19:46
  • Sorry, let me look at those other links you mentioned. – kevin.key Oct 26 '11 at 19:47
  • On the other hand, you could detect the entire board and do a simple `warpPerspective()` to achieve the effect that was showed [here](http://stackoverflow.com/questions/7838487/executing-cvwarpperspective-for-a-fake-deskewing-on-a-set-of-cvpoint). Would that work for you? – karlphillip Oct 26 '11 at 20:00
  • Well, a chess board looks like a rectangular shape, wouldn't you agree? Take a look at OpenCV's example called **squares**. It shows how to detect just that. It might need some tweaks here and there to suit your case, but you'll get the idea. – karlphillip Oct 27 '11 at 01:21
-1

findhomography() is not bad choice, but skew,distortion(camera lens) is real problem..

C++: Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray() )

Python: cv2.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask]]]) → retval, mask

C: void cvFindHomography(const CvMat* srcPoints, const CvMat* dstPoints, CvMat* H, int method=0, double ransacReprojThreshold=3, CvMat* status=NULL)

http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#findhomography

plan9assembler
  • 2,852
  • 1
  • 22
  • 13