0
votes

I'm programming a motion detection system using Raspberry Pi, the official Raspberry Pi Camera and OpenCV with Python. While I'm using the absdiff and bitwise_and operation it comes up with this:

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cvtColor, file /home/pi/opencv-2.4.10/modules/imgproc/src/color.cpp, line 3739 Traceback (most recent call last): File "icanseeu-diff.py", line 18, in t_minus = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY) cv2.error: /home/pi/opencv-2.4.10/modules/imgproc/src/color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function cvtColor

Here is the code:

import cv2
from picamera.array import PiRGBArray
from picamera import PiCamera
import time

camera = PiCamera()
camera.resolution = (320, 240)
camera.framerate = 30
camera.rotation = 180 
rawCapture = PiRGBArray(camera, size = (320, 240))

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

# Read three images first
frame1 = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY)
frame2 = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY)
frame3 = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY)

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

    # Read next image
    frame1 = frame2
    frame2 = frame3
    frame3 = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY)

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

Seems like an assignation problem, but I don't know how to deal with it. What should I do? Thanks!

3
Shouldn't you be capturing your images using the rgb format instead of bgr as your PiRGBArray is designed to take rgb images? - mpursuit

3 Answers

0
votes

To save your time, I have built a completed application to detect motion and notify to the iOS/Android. The notification will have text, image, and video. Check this out

0
votes

The error message that you are getting is informing you that image that you are passing does not have 3 or 4 channels. This is the assestion that has failed.

This is because camera.capture function does not return any values (API Documentation). Instead the rawCapture gets updated, it is this that you should be passing to cvtColor.

Instead of

frame1 = cv2.cvtColor(camera.capture(rawCapture, format = "bgr", use_video_port = True), cv2.COLOR_RGB2GRAY)

Use

rawCapture.truncate()
camera.capture(rawCapture, format = "bgr", use_video_port = True)
frame1 = cv2.cvtColor(rawCapture.array, cv2.COLOR_BGR2GRAY)

And the same for each time you capture an image.

I haven't been able to test this as I don't currently have my Raspberry Pi and Camera on me but it should fix the problem.

0
votes

I think you didn't close your camera, so python thinks that the camera is used by another program. Try to restart your Pi. The program should work after the restart. The second start of the program after the restart won't work. If this happens, close the camera in the last if-statement.