0
votes

I am trying to detect objects using OpenCV and python. This is my code I tried to run.

import cv2

def diffImg(t0, t1, t2):
  d1 = cv2.absdiff(t2, t1)
  d2 = cv2.absdiff(t1, t0)
  return cv2.bitwise_and(d1, d2)

cam = cv2.VideoCapture(1)

winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)

# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_BGR2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_BGR2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_BGR2GRAY)

while True:
  cv2.imshow( winName, diffImg(t_minus, t, t_plus) )

  # Read next image
  t_minus = t
  t = t_plus
  t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_GRAY2BGR)

  key = cv2.waitKey(10)
  if key == 27:
    cv2.destroyWindow(winName)
    break

When I run this code it gives following error.

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file ..\..\..\..\opencv\modules\imgproc\src\color.cpp, line 3739
Traceback (most recent call last):
  File "C:/Users/Ravi/PycharmProjects/Test/thread1.py", line 14, in <module>
    t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_BGR2GRAY)
cv2.error: ..\..\..\..\opencv\modules\imgproc\src\color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor

I have tried with changing color.BRG2GRAY for several ways(RGB2GRAY...etc) and I have tried using my default web cam and other usb web cam. But both ways it gives same error. What can I do to solve this matter ?

When I run the same code in Ubuntu platform, it gives following error.

Traceback (most recent call last):
  File "/home/ravi/PycharmProjects/Test/thread1.py", line 11, in <module>
    cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)
AttributeError: 'module' object has no attribute 'CV_WINDOW_AUTOSIZE'
2
the error means your input images doesnt have 3 or 4 channels, which is assumed for color images. I dont know about the python api but does cam.read()[1] mean that you use only channel number 1? please try cam.read() instead. - Micka
I tried it, but it gives src is not a numerical tuple error @Micka - RYJ
can you read the image to a variable instead and imshow the unmodified image? and test whether the captured image is empzy, in advance? - Micka

2 Answers

0
votes

cam.read() actually returns 2 values (you probably wont be needing the first value).

So try this:

cam = cv2.VideoCapture(1)
winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)

_,frame1 = cam.read()
_,frame2 = cam.read()
_,frame3 = cam.read()

# Read three images first:
t_minus = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
t = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
t_plus = cv2.cvtColor(frame3, cv2.COLOR_BGR2GRAY)

And similarly for the next section:

while True:
  cv2.imshow( winName, diffImg(t_minus, t, t_plus) )

  # Read next image
  t_minus = t
  t = t_plus
  _,frame = cam.read()
  t_plus = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)

  key = cv2.waitKey(10)
  if key == 27:
    cv2.destroyWindow(winName)
    break
0
votes

For Ubuntu platform: just change the attribute cv2.CV_WINDOW_AUTOSIZE to cv2.WINDOW_NORMAL.This is due to opencv version i think

import cv2

def diffImg(t0, t1, t2):
  d1 = cv2.absdiff(t2, t1)
  d2 = cv2.absdiff(t1, t0)
  return cv2.bitwise_and(d1, d2)

cam = cv2.VideoCapture(0)

winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.WINDOW_NORMAL)

# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

while True:
  cv2.imshow( winName, diffImg(t_minus, t, t_plus) )

  # Read next image
  t_minus = t
  t = t_plus
  t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

  key = cv2.waitKey(10)
  if key == 27:
    cv2.destroyWindow(winName)
    break