oray_Pi
Posts: 1
Joined: Sun Mar 04, 2018 8:12 pm

Raw pixel data from camera?

Sun Mar 04, 2018 8:22 pm

I am using a variant of the light weight motion detection here:
viewtopic.php?t=45235

It works well for the most part. I am using it to detect when the school bus drives by in the morning on the adjacent street which gives us a couple minutes heads up warning before it arrives. I am only looking at a very narrow area of the image which is above normal car height.

Occasionally I get false positives from garbage trucks though and I would like to screen for the color yellow.

Is there a way to grab the RGB values for just a few pixels so I can screen for the color yellow?

sanjaya
Posts: 14
Joined: Thu Jul 05, 2018 11:00 am

Re: Raw pixel data from camera?

Wed Jul 11, 2018 3:37 am

the expectation i got from reading the title was "betrayed" after reading the content.
reckon that you'd have faster and better respond by replying on the thread you mentioned.

anyway, this is a minimalist implementation that might serve your need

Code: Select all

import cv2
import numpy as np

# lo_h might be bigger than hi_h due to cyclic nature of hsv colorspace
lo_h, lo_s, lo_v = 110,  50,  50   # hsv threshold h(0-180), s (0-255), v(0, 255)
hi_h, hi_s, hi_v = 130, 255, 255   # hsv threshold

crop_x0, crop_y0 =  50,  20                        # top-left coordinate for crop region
crop_h , crop_w  = 120, 200                        # height and width of crop region
crop_x1, crop_y1 =  crop_x0+crop_w, crop_y0+crop_h # bottom-right coordinate for crop region

min_blob = crop_h * crop_w / 5 # set passing criteria at 20%

camera_id, width, height = 0, 640, 480 # change camera index accordingly

cam = cv2.VideoCapture(camera_id) 
cam.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, height)

def filter_hsv(img, lo_h, hi_h, lo_s, hi_s, lo_v, hi_v):
  hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
  if lo_h > hi_h:
    upper = cv2.inRange(hsv
      , np.array([lo_h, lo_s, lo_v])
      , np.array([180, hi_s, hi_v]))
    lower = cv2.inRange(hsv
      , np.array([   0, lo_s, lo_v])
      , np.array([hi_h, hi_s, hi_v]))
    return cv2.bitwise_or(lower, upper)
  else:
    return cv2.inRange(hsv
      , np.array([lo_h, lo_s, lo_v])
      , np.array([hi_h, hi_s, hi_v]))

while True:
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break
  ret, frame = cam.read()
  if frame is None or ret == False or len(frame) == 0:
    continue

  # main pipeline
  crop_img = frame[crop_y0:crop_y1, crop_x0:crop_x1]
  bw = filter_hsv(crop_img, lo_h, hi_h, lo_s, hi_s, lo_v, hi_v)
  aliens = cv2.countNonZero(bw)
  
  if aliens > min_blob: # aliens detected; sound the alarm or something
    frame = cv2.circle(frame, (width-crop_x0, 40), 20, (  0, 255,   0), -1)
    frame = cv2.circle(frame, (width-crop_x0, 40), 22, (255, 255, 255),  3)

  # just for presentation
  hsv = cv2.cvtColor(bw   , cv2.COLOR_GRAY2BGR)
  alpha_s = hsv[:, :, 2] / 255.0
  alpha_l = 1.0 - alpha_s
  for c in range(0, 2):
    frame[crop_y0:crop_y1, crop_x0:crop_x1, c] = (alpha_s * hsv[:, :, c]
      + alpha_l * frame[crop_y0:crop_y1, crop_x0:crop_x1, c])
  frame = cv2.rectangle(frame, (crop_x0, crop_y0), (crop_x1, crop_y1), (0, 0, 0), 3)

  cv2.imshow('view', frame)

cam.release()
cv2.destroyAllWindows()


notes:
- it should be easy to find reference on how to use opencv in python.
- the code would run in a loop; terminated by hitting the q key.
- hsv is chosen because it is more linear representation than rgb
- filtering to blue; change the hsv accordingly to filter to your shade of yellow.
- hardcoded crop area - change it accordingly
- instead of proper blob detection, simple pixel count is used to check (again, this is hardcoded)

Return to “Camera board”