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