1

I'm using - RaspberryPi4 - Raspberry camera ver2.1 - Python3 - OpenCV3 trying to catch a color from movie and success-ed with like this,

But because of AWB/AE, sometime misses the target.

I tryed to stop them

  1. OpenCVs ".set" command

    --> not supported

  2. "raspivid" command

    --> not correct

  3. picamera.camera() module

    --> cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) is error.

I couldn't find out the right way. Hope to help, thank you.

takuaya
  • 21
  • 3
  • 1
    Of course its possible to miss the target sometimes for a short time. It depends on many things. But you may hold the last coordinate of the target until the next detection. – Yunus Temurlenk Jun 10 '20 at 06:19
  • Hello and welcome to SO. I'm not big expert, but AFAIK you'd better have turned on AWB/AE. You should read more about taking picture programtically with camera. It has many dependency, but general flow is to "trigger search focus" -> "lock focus" -> "trigger search exposure" -> "lock exposure" -> "trigger search WB" -> "lock WB" -> "take picture". If any of steps failed or timeouted, then you have to handle it properly. – 404pio Jun 10 '20 at 08:07
  • it is unclear what you wan to do exactly : are you trying to turn off auto white balance and auto exposure ? if so then why are you trying to convert BGR to HSV ? – antoine Jun 10 '20 at 09:01
  • Thank you for rel. to anotoine, BGR to HSV is easier to find the color with choice HUE. – takuaya Jun 10 '20 at 09:21
  • [this](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html) is aimost same as my code. – takuaya Jun 11 '20 at 00:09

2 Answers2

1

Solve it myself

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import picamera
import time

from picamera.array import PiRGBArray
from picamera import PiCamera

def detect(img):
    hsv_min = np.array([20,100,80])
    hsv_max = np.array([27,255,255])
    masked = cv2.inRange(img, hsv_min, hsv_max)

    return masked


def main():
    #camera mode
    camera = PiCamera()
    camera.resolution = (640, 480)
    camera.framerate = 20
    camera.awb_mode = 'fluorescent'
    camera.awb_gains = 4
    camera.exposure_mode = 'off'
    capture = PiRGBArray(camera, size=(640, 480))

    # allow the camera to warmup
    time.sleep(0.1)

    for frame in camera.capture_continuous(capture, format="bgr", use_video_port=True):
        image = frame.array
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

        mask = detect(hsv)

        label = cv2.connectedComponentsWithStats(mask)

        cv2.imshow("Image", image)
        cv2.imshow("Mask", mask)

        key = cv2.waitKey(1) & 0xFF
        capture.truncate(0)

        if cv2.waitKey(25) & 0xFF == ord('q'):
            break

if __name__ == '__main__':
    main() 

thank you for cooperation!

takuaya
  • 21
  • 3
0

There are properties to control auto white balance (CAP_PROP_AUTO_WB) and auto exposure (CAP_PROP_AUTO_EXPOSURE).

As far as I know, you can use them in python (instead of raw integer value like in the code you linked to) :

cap = cv2.VideoCapture(0, cv2.CAP_V4L2)
cap.set(cv2.CAP_PROP_AUTO_EXPOSURE,0)
cap.set(cv2.CAP_PROP_AUTO_WB,0)

But be aware that this doesn't work with all backends, at least GStreamer doesn't provide a way to control camera parameter, with V4L2 it depends on the camera driver.

You can force the API to use by passing it at a second argument to VideoCapture constructor.

antoine
  • 1,653
  • 11
  • 23
  • Thank you, but unfortunately, I tried the way. You are right that my camea (= raspberrypi cam) may be not supported cap.set(15,0)/cap.set(16,0) because it doesn't work. capset(10,*) worked. – takuaya Jun 10 '20 at 09:38