Re: PureBasic Interface to OpenCV
Posted: Wed Jan 01, 2014 12:18 pm
				
				http://opencv.org/opencv-2-4-8.html is out.. 
			http://www.purebasic.com
https://www.purebasic.fr/english/
I'm having trouble working out the following Structure / Function:I'm in the process of writing an image comparison (SIFT - Scale Invariant Feature Transform) example
Code: Select all
*spilltree.CvFeatureTree = cvCreateKDTree(*descriptors)Nice work, JHPJHPJHPJHP wrote:Added 2 examples based on a question Philippe-felixer76-3 had about using a PureBasic image with OpenCV.
- cv_pbimage_1.pb: formats a PureBasic image to work with OpenCV
- cv_pbimage_2.pb: formats a PureBasic image to work with OpenCV (contributed by Philippe-felixer76-3)
-- using a faster formatting method then cv_pbimage_1.pb
-------------------------------
Repost
- for anyone interested - there's going to be a delay completing this example:I'm having trouble working out the following Structure / Function:I'm in the process of writing an image comparison (SIFT - Scale Invariant Feature Transform) example
- Structure / Function included with latest updateNB*: If anyone is interested in working on this... I can post more information; let me know.Code: Select all
*spilltree.CvFeatureTree = cvCreateKDTree(*descriptors)
I find this interesting also.AAT wrote:Hi, JHPJHP
For now I study an example "Number Plate Recognition" (written on C++) from https://github.com/MasteringOpenCV/code ... ecognition
and I can't initialize and to work with SVM in PB. Can you give me any advice or help, please?
Good luck!
Code: Select all
IncludeFile "includes/cv_functions.pbi"
Global GetCV.b, *save.IplImage, ExitCV.b, lpPrevWndFunc
;--------------------------------------------------------------
#Pdebug = 0         ; =1 - to display all images ans debug info
;--------------------------------------------------------------
#CV_WINDOW_NAME = "Number plate recognition"
#CV_DESCRIPTION = "Number plate recognition"
#CV_SHAPE_RECT            = 0
#CV_SHAPE_CROSS           = 1
#CV_SHAPE_ELLIPSE         = 2
#CV_SHAPE_CUSTOM          = 100
#CV_MOP_ERODE             = 0
#CV_MOP_DILATE            = 1
#CV_MOP_OPEN              = 2
#CV_MOP_CLOSE             = 3
#CV_MOP_GRADIENT          = 4
#CV_MOP_TOPHAT            = 5
#CV_MOP_BLACKHAT          = 6
Structure IplConvKernel Align #PB_Structure_AlignC
  nCols.l
  nRows.l
  anchorX.l
  anchorY.l
  *values.LONG
  nShiftR.l              
EndStructure
ImportC "opencv_imgproc248.lib"
  cvGetRectSubPix(*src, *dst, centerx.f, centery.f)
EndImport
Procedure WindowCallback(hWnd, Msg, wParam, lParam)
  Select Msg
    Case #WM_COMMAND
      Select wParam
        Case 1
          GetCV = #True
          keybd_event_(#VK_ESCAPE, 0, 0, 0)
        Case 2
          FileName.s = SaveFile()
          If FileName
            params.SAVE_INFO
            Select LCase(GetExtensionPart(FileName))
              Case "jpeg", "jpg", "jpe"
                params\paramId = #CV_IMWRITE_JPEG_QUALITY
                params\paramValue = 95
              Case "png"
                params\paramId = #CV_IMWRITE_PNG_COMPRESSION
                params\paramValue = 3
              Case "ppm", "pgm", "pbm"
                params\paramId = #CV_IMWRITE_PXM_BINARY
                params\paramValue = 1
              Default
                Select SelectedFilePattern()
                  Case 0
                    FileName + ".jpg"
                    params\paramId = #CV_IMWRITE_JPEG_QUALITY
                    params\paramValue = 95
                  Case 1
                    FileName + ".png"
                    params\paramId = #CV_IMWRITE_PNG_COMPRESSION
                    params\paramValue = 3
                  Case 2
                    FileName + ".ppm"
                    params\paramId = #CV_IMWRITE_PXM_BINARY
                    params\paramValue = 1
                EndSelect
            EndSelect
            cvSaveImage(FileName, *save, @params)
          EndIf
        Case 10
          keybd_event_(#VK_ESCAPE, 0, 0, 0)
      EndSelect
    Case #WM_DESTROY
      ExitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure
ProcedureC CvMouseCallback(event, x, y, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      *save.IplImage = *param\uPointer1
      DisplayPopupMenu(0, *param\uValue)
  EndSelect
EndProcedure
Procedure OpenCV(ImageFile.s)
  If FileSize(ImageFile) > 0
    
    brect.CvRect 
    
    cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_NORMAL)
    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(1, "Open")
      MenuBar()
      MenuItem(2, "Save")
      MenuBar()
      MenuItem(10, "Exit")
    EndIf
    hwnd = GetParent_(window_handle)
    ExtractIconEx_("shell32.dll", 1, #Null, @phiconSmall, 1)
    SendMessage_(hwnd, #WM_SETICON, 0, phiconSmall)
    wStyle = GetWindowLongPtr_(hwnd, #GWL_STYLE)
    SetWindowLongPtr_(hwnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
    *image.IplImage = cvLoadImage(ImageFile, #CV_LOAD_IMAGE_ANYDEPTH | #CV_LOAD_IMAGE_ANYCOLOR)
    
    iWidth = *image\width
    iHeight = *image\height
    cvResizeWindow(#CV_WINDOW_NAME, iWidth, iHeight)
  
    cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
    ToolTip(window_handle, #CV_DESCRIPTION)
    
    If *image\nChannels = 1
      *gray.IplImage = cvCloneImage(*image)
    Else
      *gray.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
      cvCvtColor(*image, *gray, #CV_BGR2GRAY, 1)
    EndIf
    If #Pdebug 
      cvShowImage("Gray", *gray)
    EndIf
    
    cvSmooth(*gray, *gray, #CV_BLUR, 5, 0, 0, 0)
    
    *img_sobel.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
    cvSobel(*gray, *img_sobel, 1, 0, 3)
    If #Pdebug 
      cvShowImage("Sobel", *img_sobel)
    EndIf  
    
    *img_threshold.IplImage = cvCloneImage(*img_sobel)
    threshold.d = cvThreshold2(*img_sobel, *img_threshold, 0, 255, #CV_THRESH_BINARY + #CV_THRESH_OTSU)    
    If #Pdebug 
      cvShowImage("Tresh", *img_threshold)      
    EndIf  
    
    *ConvKernel.IplConvKernel = cvCreateStructuringElementEx(17, 5, 0, 0, #CV_SHAPE_RECT, 0)
    *temp.IplImage = cvCloneImage(*img_threshold)
    cvMorphologyEx(*img_threshold, *img_threshold, *temp, *ConvKernel, #CV_MOP_CLOSE, 1)
    If #Pdebug 
      cvShowImage("Morphology", *img_threshold) 
    EndIf
    
    *storage.CvMemStorage = cvCreateMemStorage(0)
    cvClearMemStorage(*storage)
    *contours.CvSeq    
    nContours = cvFindContours(*img_threshold, *storage, @*contours, SizeOf(CvContour), #CV_RETR_EXTERNAL, #CV_CHAIN_APPROX_NONE, 0, 0)     
    
    *contour.IplImage = cvCreateImage(*gray\width, *gray\height, #IPL_DEPTH_8U, 3)
    cvSet(*contour, 5, 5, 5, 0, #Null)
    
    box.CvBox2D
    Dim pt1.CvPoint2D32f(4)
    Dim boxes.CvBox2D(0)
    
    aspect.f = 45.0 /77.0
    error.f = 0.35
    minHeight.f = 28
    maxHeight.f = 55   
    minAspect.f = 0.18;
    maxAspect.f = aspect+aspect*error;    
    
    boxcntr.l=0    
    
    For rtnCount = 0 To nContours - 1
      area.d = cvContourArea(*contours, 0, #CV_WHOLE_SEQ_END_INDEX, 0)
      If area >= 1000 And area <= 7000 
        cvMinAreaRect2(@box, *contours, #Null)
          
        If Abs(box\angle) < 45 
          charAspect.d = Box\size\height / Box\size\width 
          bheight.d = Box\size\height
        Else
          charAspect.d = Box\size\width / Box\size\height
          bheight.d = Box\size\width 
        EndIf
        
        bbArea.d=Box\size\width * Box\size\height
        percPixels.d = area / bbArea
        
        If  charAspect > minAspect And charAspect < maxAspect And percPixels < 0.8 And bheight >= minHeight And bheight < maxHeight
          cvBoxPoints(box\center\x, box\center\y, box\size\width, box\size\height, box\angle, pt1())
          For pc = 0 To 3
           cvLine(*contour, pt1(pc)\x, pt1(pc)\y, pt1((pc+1)%4)\x, pt1((pc+1)%4)\y, 0, 255, 255, 0, 2, #CV_AA, 0)
          Next pc                     
          cvDrawContours(*contour, *contours, 255, 155, 0, 0, 155, 255, 0, 0, -1, 1, #CV_AA, 0, 0)
          boxcntr + 1
          boxes(boxcntr-1) = box
          ReDim boxes(boxcntr)          
        EndIf        
      EndIf    
      *contours = *contours\h_next
    Next
    
    If #Pdebug            
      cvShowImage("Contours", *contour)        
      Debug("BoxCntr="+Str(boxcntr))        
      Debug("NContours="+Str(nContours))     
    EndIf
  
    *result.IplImage = cvCloneImage(*image)
    *mask.IplImage = cvCreateImage(*image\width+2, *image\height+2, #IPL_DEPTH_8U, 1)
    cvSet(*mask, 0, 0, 0, 0, #Null)     
    
    For bx=0 To boxcntr-1
      cvCircle(*result, boxes(bx)\center\x, boxes(bx)\center\y, 2, 0, 255, 0, 0, 2, #CV_AA, 0)
      If boxes(bx)\size\width > boxes(bx)\size\height
        minSize.f = boxes(bx)\size\height
        maxSize.f = boxes(bx)\size\width
      Else
        minSize.f = boxes(bx)\size\width
        maxSize.f = boxes(bx)\size\height
      EndIf
      minSize = minSize - minSize*0.5
      maxSize = maxSize - maxSize*0.5
      loDiff.l = 30; 
      upDiff.l = 30;
      NumSeeds.l = 10;
      ccomp.CvRect
      
      cvSet(*mask, 0, 0, 0, 0, #Null)       
      connectivity.l = 4;
      newMaskVal.l = 255;      
      flags.l = connectivity + (newMaskVal << 8) + #CV_FLOODFILL_FIXED_RANGE  + #CV_FLOODFILL_MASK_ONLY  ;
      If #Pdebug
        Debug("minSize="+StrF(minSize))
      EndIf
    
      For j=1 To NumSeeds
        seed.cvPoint
        seed\x=boxes(bx)\center\x+Random(maxSize)-maxSize/2
        seed\y=boxes(bx)\center\y+Random(minSize)-minSize/2       
        cvCircle(*result, seed\x, seed\y, 1, 0, 255, 255, 0, 1, #CV_AA, 0)
        comp.CvConnectedComp
        iarea.l = cvFloodFill(*image, seed\x, seed\y, 255, 0, 0, 0, loDiff, loDiff, loDiff, 0, upDiff, upDiff, upDiff, 0, @comp, flags, *mask)
      Next j
      #CV_SEQ_ELTYPE_POINT = CV_MAKETYPE(#CV_32S, 2)   
      *seq.CvSeq = cvCreateSeq(#CV_SEQ_ELTYPE_POINT, SizeOf(CvSeq), SizeOf(CvPoint), *storage)
      pointsInterest.CvPoint
      k=0    
      For j = 0 To *mask\height-1         
        *pt = *mask\imageData + j*(*mask\widthstep)
        For i = 0 To *mask\width-1         
          *ptr = *pt + i
          If PeekC(*ptr)=255
            pointsInterest\x = i
            pointsInterest\y = j
            cvSeqPush(*seq, @pointsInterest)
            k + 1          
          EndIf              
        Next i      
      Next j      
      
      If #Pdebug      
        Debug("Points in mask: "+Str(k))
      EndIf
      
      minRect.CvBox2D
      cvMinAreaRect2(@minRect, *seq, #Null)
      If Abs(minRect\angle) < 45 
        charAspect.d = minRect\size\height / minRect\size\width 
        bheight.d = minRect\size\height
      Else
        charAspect.d = minRect\size\width / minRect\size\height
        bheight.d = minRect\size\width 
      EndIf
      
      bbArea.d=minRect\size\width * minRect\size\height
      percPixels.d = area / bbArea
      
      If #Pdebug
        Debug("charAspect="+StrD(charAspect)+";  %Pixels="+StrD(percPixels)+";  Angle="+StrF(Box\angle)+"  bHeight="+StrF(bheight))
      EndIf
          
      If  charAspect > minAspect And charAspect < maxAspect And bheight >= minHeight And bheight < maxHeight
        cvBoxPoints(minRect\center\x, minRect\center\y, minRect\size\width, minRect\size\height, minRect\angle, pt1())               
        For pc = 0 To 3
;          cvLine(*result, pt1(pc)\x, pt1(pc)\y, pt1((pc+1)%4)\x, pt1((pc+1)%4)\y, 0, 255, 255, 0, 1, #CV_AA, 0)
          cvLine(*image, pt1(pc)\x, pt1(pc)\y, pt1((pc+1)%4)\x, pt1((pc+1)%4)\y, 0, 255, 255, 0, 2, #CV_AA, 0)          
        Next pc 
        
        r.f = minRect\size\width / minRect\size\height
        rotangle.f = minRect\angle
        If r < 1
          rotangle=90+minRect\angle
        EndIf
        
        If #Pdebug
          Debug("Angle="+StrF(minRect\angle)+"   rotAngle="+StrF(rotangle))
        EndIf
                     
        *rotmat.CvMat = cvCreateMat(2, 3, CV_MAKETYPE(#CV_32F, 1))
        cv2DRotationMatrix(minRect\center\x, minRect\center\y, rotangle, 1, *rotmat)
      
        *img_rotated.IplImage = cvCloneImage(*image)
        cvWarpAffine(*image, *img_rotated, *rotmat, #CV_INTER_CUBIC, 0, 255, 0, 0)    
        
        rect_size.CvSize2D32f
        rect_size\width = minRect\size\width
        rect_size\height = minRect\size\height
        
        If r < 1
          buf.f = rect_size\width                   ;swap
          rect_size\width = rect_size\height
          rect_size\height = buf
        EndIf
        *img_crop.IplImage = cvCreateImage(rect_size\width, rect_size\height, #IPL_DEPTH_8U, *img_rotated\nChannels)
        cvGetRectSubPix(*img_rotated, *img_crop, minRect\center\x, minRect\center\y)
        
        If #Pdebug 
          cvShowImage("img_crop", *img_crop) 
        EndIf
      
        *resultResized.IplImage = cvCreateImage(144, 33, #IPL_DEPTH_8U, *img_crop\nChannels)
        cvResize(*img_crop, *resultResized, #CV_INTER_CUBIC)
        
        *grayResult.IplImage = cvCreateImage(*resultResized\width, *resultResized\height, #IPL_DEPTH_8U, 1)
        cvCvtColor(*resultResized, *grayResult, #CV_BGR2GRAY, 1)
        cvSmooth(*grayResult, *grayResult, #CV_BLUR, 3, 0, 0, 0)
        cvEqualizeHist(*grayResult, *grayResult)
        
;---> SVM here
        
        *img_threshold2.IplImage = cvCreateImage(*resultResized\width, *resultResized\height, #IPL_DEPTH_8U, 1)
        threshold2 = cvThreshold2(*grayResult, *img_threshold2, 60, 255, #CV_THRESH_BINARY_INV)    
        
        cvClearMemStorage(*storage)
        *contours2.CvSeq      
        nContours2 = cvFindContours(*img_threshold2, *storage, @*contours2, SizeOf(CvContour), #CV_RETR_EXTERNAL, #CV_CHAIN_APPROX_NONE, 0, 0)
        
        For rtnCount = 0 To nContours2 - 1
;            cvDrawContours(*resultResized, *contours2, 255, 155, 0, 0, 155, 255, 0, 0, -1, 1, #CV_AA, 0, 0)
          cvBoundingRect(@brect, *contours2, 1);
          cvRectangleR(*resultResized, brect\x-1, brect\y-1, brect\width+2, brect\height+2, 70, 70, 255, 0, 1, CV_AA, 0);           
          *contours2 = *contours2\h_next
        Next       
        If #Pdebug 
          cvShowImage("Eq_gray", *grayResult)          
          cvShowImage("Tresh2", *img_threshold2)           
          cvShowImage("img_resize", *resultResized)     
        EndIf
        
        cvSetImageROI(*image, boxes(bx)\center\x-50, boxes(bx)\center\y-65, 144, 33)
        cvAndS(*image, 0, 0, 0, 0, *image, #Null)
        cvAdd(*image, *resultResized, *image, #Null)
        cvResetImageROI(*image)              
        
      EndIf           
    Next bx        
  
    If #Pdebug 
      cvShowImage("img_rotated", *img_rotated) 
      cvShowImage("Mask", *mask)
      cvShowImage("Result", *result) 
    EndIf  
    
    *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
    *param\uPointer1 = *image
    *param\uValue = window_handle
    cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)
    Repeat
      If *image
        cvShowImage(#CV_WINDOW_NAME, *image)
        keyPressed = cvWaitKey(0)
      EndIf
    Until keyPressed = 27 Or ExitCV
    FreeMemory(*param)
    
    cvReleaseImage(@*image)
    cvReleaseImage(@*gray)
    cvReleaseImage(@*img_sobel)
    cvReleaseImage(@*img_threshold)
    cvReleaseImage(@*temp)
    cvReleaseImage(@*contour)
    cvReleaseImage(@*result)
    cvReleaseImage(@*mask)
    cvReleaseImage(@*img_rotated)
    cvReleaseImage(@*img_crop)
    cvReleaseImage(@*resultResized)
    cvReleaseImage(@*grayResult)
    cvReleaseImage(@*img_threshold2)
    
    cvDestroyWindow(#CV_WINDOW_NAME)
    If #Pdebug 
      cvDestroyWindow("Gray")       
      cvDestroyWindow("Sobel")     
      cvDestroyWindow("Tresh")      
      cvDestroyWindow("Morphology")      
      cvDestroyWindow("Contours")
      cvDestroyWindow("img_crop")
      cvDestroyWindow("Eq_gray")         
      cvDestroyWindow("Tresh2")          
      cvDestroyWindow("img_resize") 
      cvDestroyWindow("img_rotated")
      cvDestroyWindow("Mask")
      cvDestroyWindow("Result")
    EndIf  
    If GetCV
      GetCV = #False
      ExitCV = #False
      OpenCV(GetImage())
    EndIf
  EndIf
EndProcedure
ExamineDesktops()
OpenCV(GetImage())