hi, guys.
This is an example how to correct webcam's image distortions. The example is based on JHPJHP's example cv_cam_chessboard_2.pb.
You have to use binaries/images/chessboard.jpg during the calibration process.
You have to slightly move and rotate webcam along chessboard (or chessboard along webcam) during calibration.
Save code as cv_cam_undistort.pb in main folder with JHPJHP's examples.
Code: Select all
IncludeFile "includes/cv_functions.pbi"
Global lpPrevWndFunc
#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_WINDOW2_NAME = "Corrected image"
#CV_DESCRIPTION = "Calibrating of the webcam with 10 x 7 chessboard pattern then shows corrected image." + Chr(10) + Chr(10) +
"Press S key to save the pair of raw and corrected images" + Chr(10) + Chr(10) +
"Press Esc key to exit"
#CORNER_ROW = 6
#CORNER_COL = 9
#IMAGE_SIZE = 25
#PATTERN_SIZE = #CORNER_ROW * #CORNER_COL
#ALL_POINTS = #IMAGE_SIZE * #PATTERN_SIZE
ProcedureC WindowCallback(hWnd, Msg, wParam, lParam)
Shared exitCV.b
Select Msg
Case #WM_COMMAND
Select wParam
Case 10
exitCV = #True
EndSelect
Case #WM_DESTROY
exitCV = #True
EndSelect
ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure
ProcedureC CvMouseCallback(event, x.l, y.l, flags, *param.USER_INFO)
Select event
Case #CV_EVENT_RBUTTONDOWN
DisplayPopupMenu(0, *param\uValue)
Case #CV_EVENT_LBUTTONDBLCLK
EndSelect
EndProcedure
Repeat
nCreate + 1
*capture.CvCapture = cvCreateCameraCapture(#CV_CAP_ANY)
Until nCreate = 5 Or *capture
If *capture
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
*window_name = cvGetWindowName(window_handle)
lpPrevWndFunc = SetWindowLongPtr_(window_handle, #GWL_WNDPROC, @WindowCallback())
If CreatePopupImageMenu(0, #PB_Menu_ModernLook)
MenuItem(10, "Exit")
EndIf
hWnd = GetParent_(window_handle)
opencv = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
SendMessage_(hWnd, #WM_SETICON, 0, opencv)
wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
ToolTip(window_handle, #CV_DESCRIPTION)
*param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
*param\uValue = window_handle
cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)
font.CvFont : cvInitFont(@font, #CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, #Null, 1, #CV_AA)
FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
Dim corners.CvPoint2D32f(#ALL_POINTS)
Dim points(#IMAGE_SIZE)
*source.IplImage
*image.IplImage
*gray.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 1)
DBL_EPSILON.d = 2.2204460492503131 * Pow(10, -16)
While found_num < #IMAGE_SIZE
*image = cvQueryFrame(*capture)
If *image
cvReleaseImage(@*source)
*source = cvCloneImage(*image)
cvCvtColor(*source, *gray, #CV_BGR2GRAY, 1)
If cvCheckChessboard(*gray, #CORNER_COL, #CORNER_ROW)
found = cvFindChessboardCorners(*source, #CORNER_COL, #CORNER_ROW, @corners(found_num * #PATTERN_SIZE), @corner_count, #CV_CALIB_CB_ADAPTIVE_THRESH | #CV_CALIB_CB_FILTER_QUADS)
If found
cvFindCornerSubPix(*gray, @corners(found_num * #PATTERN_SIZE), corner_count, 3, 3, -1, -1, #CV_TERMCRIT_ITER | #CV_TERMCRIT_EPS, 20, 0.03)
cvDrawChessboardCorners(*source, #CORNER_COL, #CORNER_ROW, @corners(found_num * #PATTERN_SIZE), corner_count, found)
points(found_num) = corner_count
found_num + 1
EndIf
EndIf
cvPutText(*source, "Found "+Str(found_num)+"/"+Str(#IMAGE_SIZE)+" chessboard images", 10, 30, @font, 0, 0, 255, 0)
cvShowImage(#CV_WINDOW_NAME, *source)
keyPressed = cvWaitKey(100)
EndIf
If keyPressed = 27 Or exitCV : Break : EndIf
Wend
If found_num = #IMAGE_SIZE
cvPutText(*image, "The camera calibration, wait a little...", 10, 30, @font, 0, 0, 255, 0)
cvShowImage(#CV_WINDOW_NAME, *image)
keyPressed = cvWaitKey(100)
Dim objects.CvPoint3D32f(#ALL_POINTS)
#CHESS_LENGTH = 24
For i = 0 To #IMAGE_SIZE - 1
For j = 0 To #CORNER_ROW - 1
For k = 0 To #CORNER_COL - 1
objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\x = j * #CHESS_LENGTH
objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\y = k * #CHESS_LENGTH
objects(i * #PATTERN_SIZE + j * #CORNER_COL + k)\z = 0.0
Next
Next
Next
object_points.CvMat
image_points.CvMat
point_counts.CvMat
cvInitMatHeader(@object_points, #ALL_POINTS, 3, CV_MAKETYPE(#CV_32F, 1), @objects(), #CV_AUTOSTEP)
cvInitMatHeader(@image_points, #ALL_POINTS, 2, CV_MAKETYPE(#CV_32F, 1), @corners(), #CV_AUTOSTEP)
cvInitMatHeader(@point_counts, #IMAGE_SIZE, 1, CV_MAKETYPE(#CV_32S, 1), @points(), #CV_AUTOSTEP)
*camera_matrix.CvMat = cvCreateMat(3, 3, CV_MAKETYPE(#CV_32F, 1))
*distortion_coeffs.CvMat = cvCreateMat(4, 1, CV_MAKETYPE(#CV_32F, 1))
cvCalibrateCamera2(@object_points, @image_points, @point_counts, FrameWidth, FrameHeight, *camera_matrix, *distortion_coeffs, #Null, #Null, 0, #CV_TERMCRIT_ITER | #CV_TERMCRIT_EPS, 50, DBL_EPSILON)
*mapx.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 1)
*mapy.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 1)
cvInitUndistortMap(*camera_matrix, *distortion_coeffs, *mapx, *mapy)
cvNamedWindow(#CV_WINDOW2_NAME, #CV_WINDOW_AUTOSIZE)
cvMoveWindow(#CV_WINDOW2_NAME, *image\width+30, 20)
Repeat
*image = cvQueryFrame(*capture)
If *image
cvReleaseImage(@*imgundist)
*imgundist = cvCloneImage(*image)
cvUndistort2(*image, *imgundist, *camera_matrix, *distortion_coeffs, #Null)
cvShowImage(#CV_WINDOW_NAME, *image)
cvShowImage(#CV_WINDOW2_NAME, *imgundist)
EndIf
keyPressed = cvWaitKey(10)
If keyPressed = 83 Or keyPressed = 115
If FileSize("ImagePairs") <> -2 : CreateDirectory("ImagePairs") : EndIf
cvSaveImage("./ImagePairs/"+FormatDate("%yyyy-%mm-%dd %hh-%ii-%ss", Date()) + ".jpg" , *image, #Null)
cvSaveImage("./ImagePairs/"+FormatDate("%yyyy-%mm-%dd %hh-%ii-%ss", Date()) + "_Undistorted.jpg", *imgundist, #Null)
Debug "Saved"
EndIf
Until keyPressed = 27 Or exitCV
cvReleaseMat(@*distortion_coeffs)
cvReleaseMat(@*camera_matrix)
EndIf
FreeMemory(*param)
cvReleaseImage(@*gray)
cvReleaseImage(@*source)
cvReleaseImage(@*mapx)
cvReleaseImage(@*mapy)
cvDestroyAllWindows()
cvReleaseCapture(@*capture)
Else
MessageBox_(0, "Unable to connect to a webcam - operation cancelled.", #CV_WINDOW_NAME, #MB_ICONERROR)
EndIf