Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to publish opencv ROI coordinates?

Hi,

I'd like to be able to publish the coordinate data of squares that opencv puts around the items it finds onto the ros network. We use rosweb for our web interface which uses camera_functions.py.

Currently I've changed camera_functions.py to look like this:

import os
import cv
import socket
import rostools.rosthread
import time
import std_msgs
import rospy


"""
This file has been packaged with ros_cv_streamer *and* rosweb, but has been designed with
potential to be moved into its own generic package, so that filters can be shared between
many different projects, but I didn't get time.

However, instead if this, depending on how much information is accessible by the publisher,
it may be better to add this functionality to the camera server, provided that the functions
are only ever actually performing openCV processing  when the topic has at least one
subscriber. Having worked with the ROS network for a while now, I do believe this information
would be provided internally, and if it's not a feature request should be made. The only
drawback to this would be that it's forcing the processing to occur on the backend, where
cv_streamer_client executes processing on the frontend...
"""
# This is a magic path, I don't like it's use but there appears to be no standardized way to
# access the XML files...
HAAR_CASCADE_PATH = "/opt/ros/groovy/share/OpenCV/haarcascades/haarcascade_eye.xml"
opencv = std_msgs.msg.Int32MultiArray()
opencv.data = [0,0,0,0]

cv_pub = rospy.Publisher('/mechbotugv/hardware/CV', std_msgs.msg.Int32MultiArray)
time.sleep(3) 

if not os.path.exists(HAAR_CASCADE_PATH):
    print("Could not find HAAR_CASCADE_PATH in %s" % HAAR_CASCADE_PATH)


storage = cv.CreateMemStorage()
cascade = cv.Load(HAAR_CASCADE_PATH)

def detect_faces(image):
    """
    Generic facial-detection code, this will work on both RAW and jpeg streams.
    Adds a rectangle around any faces it finds (but isn't eactly the greatest
    algorithm)
    @param image: Should be a OpenCV IPLImage
    """
    faces = []
    detected = cv.HaarDetectObjects(image, cascade, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING, (100,100))
    if detected:
        for (x,y,w,h),n in detected:
            faces.append((x,y,w,h))
        opencv.data[0]=x
            opencv.data[1]=y
            opencv.data[2]=w
            opencv.data[3]=h
            pub.publish(opencv)
            rospy.sleep(1)
        for (x,y,w,h) in faces:
            cv.Rectangle(image, (x,y), (x+w,y+h), 255)
    return image


Filters = {"detect_faces":detect_faces}

But was originally like this:

import os
import cv

"""
This file has been packaged with ros_cv_streamer *and* rosweb, but has been designed with
potential to be moved into its own generic package, so that filters can be shared between
many different projects, but I didn't get time.

However, instead if this, depending on how much information is accessible by the publisher,
it may be better to add this functionality to the camera server, provided that the functions
are only ever actually performing openCV processing  when the topic has at least one
subscriber. Having worked with the ROS network for a while now, I do believe this information
would be provided internally, and if it's not a feature request should be made. The only
drawback to this would be that it's forcing the processing to occur on the backend, where
cv_streamer_client executes processing on the frontend...
"""
# This is a magic path, I don't like it's use but there appears to be no standardized way to
# access the XML files...
HAAR_CASCADE_PATH = "/opt/ros/groovy/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml"
if not os.path.exists(HAAR_CASCADE_PATH):
    print("Could not find HAAR_CASCADE_PATH in %s" % HAAR_CASCADE_PATH)


storage = cv.CreateMemStorage()
cascade = cv.Load(HAAR_CASCADE_PATH)

def detect_faces(image):
    """
    Generic facial-detection code, this will work on both RAW and jpeg streams.
    Adds a rectangle around any faces it finds (but isn't eactly the greatest
    algorithm)
    @param image: Should be a OpenCV IPLImage
    """
    faces = []
    detected = cv.HaarDetectObjects(image, cascade, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING, (100,100))
    if detected:
        for (x,y,w,h),n in detected:
            faces.append((x,y,w,h))
        for (x,y,w,h) in faces:
            cv.Rectangle(image, (x,y), (x+w,y+h), 255)
    return image


Filters = {"detect_faces":detect_faces}

The problem is, the modified code doesn't do anything. It just bombs out somewhere and doesn't even let me know.

Any help would be appreciated thanks!