with minimal additions will give a guard system with alarm zones based on a webcam.
Code: Select all
IncludeFile "includes/cv_functions.pbi"
Global lpPrevWndFunc
#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "Calculates the weighted sum of the input image and the accumulator creating a silhouette " +
                  "effect used to detect objects of a certain size." + Chr(10) + Chr(10) +
                  "- [ Z ] KEY: Toggle alarm zone (green rectangle)" + Chr(10) + Chr(10) +
                  "- SPACEBAR: Toggle between foreground/background view." + Chr(10) + Chr(10) +
                  "- [ V ] KEY: Change PIP view."
Structure zone
  xbeg.l
  xend.l
  ybeg.l
  yend.l
EndStructure
Dim guardzone.zone(8)
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, y, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\uValue)
  EndSelect
EndProcedure
Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
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)
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  
; 9 alarm zones  released
  zoneW = FrameWidth/3
  zoneH = FrameHeight/3 
  zoneN = 4                   ; start zone  
  For zoney = 0 To 2
    For zonex = 0 To 2
      xy = zoney*3 + zoneX
      guardzone(xy)\xbeg = zonex * zoneW
      guardzone(xy)\xend = guardzone(xy)\xbeg + zoneW - 1
      guardzone(xy)\ybeg = zoney * zoneH
      guardzone(xy)\yend = guardzone(xy)\ybeg + zoneH - 1      
    Next zonex    
  Next zoney
    
  INIT_TIME = 50
  BG_RATIO.d = 0.02
  OBJ_RATIO.d = 0.005
  Zeta.d = 10
  *imgAverage.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 3)
  *imgSgm.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 3)
  *imgTmp.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 3)
  *img_lower.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 3)
  *img_upper.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_32F, 3)
  *imgSilhouette.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 1)
  *imgResult.IplImage = cvCreateImage(FrameWidth, FrameHeight, #IPL_DEPTH_8U, 3)
  iRatio.d = 150 / FrameWidth
  iWidth = FrameWidth * iRatio
  iHeight = FrameHeight * iRatio
  *PIP.IplImage = cvCreateImage(iWidth, iHeight, #IPL_DEPTH_8U, 3)
  *image.IplImage
  cvSetZero(*imgAverage)
  For rtnCount = 0 To INIT_TIME
    *image = cvQueryFrame(*capture)
  
    If *image : cvAcc(*image, *imgAverage, #Null) : EndIf
  
  Next
  cvConvertScale(*imgAverage, *imgAverage, 1.0 / INIT_TIME, 0)
  cvSetZero(*imgSgm)
  
  For rtnCount = 0 To INIT_TIME
    *image = cvQueryFrame(*capture)
  
    If *image
      cvConvert(*image, *imgTmp)
      cvSub(*imgTmp, *imgAverage, *imgTmp, #Null)
      cvPow(*imgTmp, *imgTmp, 2)
      cvConvertScale(*imgTmp, *imgTmp, 2, 0)
      cvPow(*imgTmp, *imgTmp, 0.5)
      cvAcc(*imgTmp, *imgSgm, #Null)
    EndIf
  Next 
  cvConvertScale(*imgSgm, *imgSgm, 1.0 / INIT_TIME, 0)
  *storage.CvMemStorage = cvCreateMemStorage(0)
  *contours.CvContour
  *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
  *param\uValue = window_handle
  cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)
  Repeat
    *image = cvQueryFrame(*capture)
    If *image
      cvConvert(*image, *imgTmp)
      cvSub(*imgAverage, *imgSgm, *img_lower, #Null)
      cvSubS(*img_lower, Zeta, Zeta, Zeta, Zeta, *img_lower, #Null)
      cvAdd(*imgAverage, *imgSgm, *img_upper, #Null)
      cvAddS(*img_upper, Zeta, Zeta, Zeta, Zeta, *img_upper, #Null)
      cvInRange(*imgTmp, *img_lower, *img_upper, *imgSilhouette)
      cvSub(*imgTmp, *imgAverage, *imgTmp, #Null)
      cvPow(*imgTmp, *imgTmp, 2)
      cvConvertScale(*imgTmp, *imgTmp, 2, 0)
      cvPow(*imgTmp, *imgTmp, 0.5)
      cvRunningAvg(*image, *imgAverage, BG_RATIO, *imgSilhouette)
      cvRunningAvg(*imgTmp, *imgSgm, BG_RATIO, *imgSilhouette)
      cvNot(*imgSilhouette, *imgSilhouette)
      cvRunningAvg(*imgTmp, *imgSgm, OBJ_RATIO, *imgSilhouette)
      cvErode(*imgSilhouette, *imgSilhouette, #Null, 1)
      cvDilate(*imgSilhouette, *imgSilhouette, #Null, 2)
      cvErode(*imgSilhouette, *imgSilhouette, #Null, 1)
      cvMerge(*imgSilhouette, *imgSilhouette, *imgSilhouette, #Null, *imgResult)
      cvClearMemStorage(*storage)
      nContours = cvFindContours(*imgSilhouette, *storage, @*contours, SizeOf(CvContour), #CV_RETR_LIST, #CV_CHAIN_APPROX_SIMPLE, 0, 0)
      
      cvRectangleR(*image, guardzone(zoneN)\xbeg, guardzone(zoneN)\ybeg, zoneW-1, zoneH-1, 0, 255, 0, 0, 1, #CV_AA, #Null) 
      
      If nContours
        For rtnCount = 0 To nContours - 1
          area.d = cvContourArea(*contours, 0, #CV_WHOLE_SEQ_END_INDEX, 0)
          If area >= 400 And area <= 100000            
            If (*contours\rect\x + *contours\rect\width/2) => guardzone(zoneN)\xbeg And
               (*contours\rect\x + *contours\rect\width/2) <= guardzone(zoneN)\xend And
               (*contours\rect\y + *contours\rect\height/2) => guardzone(zoneN)\ybeg And
               (*contours\rect\y + *contours\rect\height/2) <= guardzone(zoneN)\yend                     
                cvDrawContours(*imgResult, *contours, 255, 155, 0, 0, 155, 255, 0, 0, -1, 2, #CV_AA, 0, 0)
                cvRectangleR(*image, *contours\rect\x, *contours\rect\y, *contours\rect\width, *contours\rect\height, 0, 0, 255, 0, 2, #CV_AA, #Null)            
            EndIf             
          EndIf
          *contours = *contours\h_next
        Next
        Select PIP
          Case 0
            If foreground
              cvResize(*image, *PIP, #CV_INTER_AREA)
              cvSetImageROI(*imgResult, 20, 20, iWidth, iHeight)
              cvAndS(*imgResult, 0, 0, 0, 0, *imgResult, #Null)
              cvAdd(*imgResult, *PIP, *imgResult, #Null)
              cvResetImageROI(*imgResult)
              cvRectangleR(*imgResult, 19, 19, iWidth + 2, iHeight + 2, 0, 255, 255, 0, 1, #CV_AA, #Null)
              cvShowImage(#CV_WINDOW_NAME, *imgResult)
            Else
              cvResize(*imgResult, *PIP, #CV_INTER_AREA)
              cvSetImageROI(*image, 20, 20, iWidth, iHeight)
              cvAndS(*image, 0, 0, 0, 0, *image, #Null)
              cvAdd(*image, *PIP, *image, #Null)
              cvResetImageROI(*image)
              cvRectangleR(*image, 19, 19, iWidth + 2, iHeight + 2, 0, 255, 255, 0, 1, #CV_AA, #Null)
              cvShowImage(#CV_WINDOW_NAME, *image)
            EndIf
          Case 1
            If foreground
              cvResize(*image, *PIP, #CV_INTER_AREA)
              cvSetImageROI(*imgResult, *image\width - (150 + 20), 20, iWidth, iHeight)
              cvAndS(*imgResult, 0, 0, 0, 0, *imgResult, #Null)
              cvAdd(*imgResult, *PIP, *imgResult, #Null)
              cvResetImageROI(*imgResult)
              cvRectangleR(*imgResult, *image\width - (150 + 21), 19, iWidth + 2, iHeight + 2, 0, 255, 255, 0, 1, #CV_AA, #Null)
              cvShowImage(#CV_WINDOW_NAME, *imgResult)
            Else
              cvResize(*imgResult, *PIP, #CV_INTER_AREA)
              cvSetImageROI(*image, *image\width - (150 + 20), 20, iWidth, iHeight)
              cvAndS(*image, 0, 0, 0, 0, *image, #Null)
              cvAdd(*image, *PIP, *image, #Null)
              cvResetImageROI(*image)
              cvRectangleR(*image, *image\width - (150 + 21), 19, iWidth + 2, iHeight + 2, 0, 255, 255, 0, 1, #CV_AA, #Null)
              cvShowImage(#CV_WINDOW_NAME, *image)
            EndIf
          Case 2
            If foreground : cvShowImage(#CV_WINDOW_NAME, *imgResult) : Else : cvShowImage(#CV_WINDOW_NAME, *image) : EndIf
        EndSelect
        keyPressed = cvWaitKey(10)
        Select keyPressed
          Case 32
            foreground ! 1
          Case 86, 118
            PIP = (PIP + 1) % 3
          Case 90, 122          
            zoneN = (zoneN + 1) % 9 
        EndSelect
      EndIf
    Else
      Break
    EndIf
  Until keyPressed = 27 Or exitCV
  FreeMemory(*param)
  cvReleaseMemStorage(@*storage)
  cvReleaseImage(@*PIP)
  cvReleaseImage(@*imgResult)
  cvReleaseImage(@*imgSilhouette)
  cvReleaseImage(@*img_upper)
  cvReleaseImage(@*img_lower)
  cvReleaseImage(@*imgTmp)
  cvReleaseImage(@*imgSgm)
  cvReleaseImage(@*imgAverage)
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)
EndIf