Search code examples
c++opencvraspberry-piobject-detection

How to use the Object Detection Bounding Box in a decision condition to turn on the LED on Raspberry Pi using C++ OpenCV?


I am using OpenCV 2.4.8 to create an Application which will detect the Guns. The application will be deployed on Raspberry Pi. An LED/Buzzer is also connected to the Raspberry Pi. If the Gun is detected, the LED/Buzzer should be turned on according to some specific condition. I have attached the relevant code. The problem is, how to tell the code that whether the gun is detected or not? I mean, the detected gun is shown by a bounding box. Now, how to use that Bounding Box in IF-Condition? I have commented out the desired lines in the code, like what I want to do actually. Can anyone please guide me how to do that? Any help is highly appreciated! Thanks.
Here is my code snippet:

for(;;)
{
    cap.retrieve(frame);
    cap >> frame; 
std::vector<Rect> guns;
Mat frame_gray;

cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);

// Detect guns
gun_cascade.detectMultiScale(frame_gray, guns, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30 , 30));

// Set Region of Interest
cv::Rect roi_b;
cv::Rect roi_c;
cv::Rect bbox;
size_t ic = 0; // ic is index of current element
int ac = 0; // ac is area of current element

size_t ib = 0; // ib is index of biggest element
int ab = 0; // ab is area of biggest element

for (ic = 0; ic < guns.size(); ic++) // Iterate through all current elements (detected guns)

{
    roi_c.x = guns[ic].x;
    roi_c.y = guns[ic].y;
    roi_c.width = (guns[ic].width);
    roi_c.height = (guns[ic].height);

    ac = roi_c.width * roi_c.height; // Get the area of current element (detected gun)

    roi_b.x = guns[ib].x;
    roi_b.y = guns[ib].y;
    roi_b.width = (guns[ib].width);
    roi_b.height = (guns[ib].height);

    ab = roi_b.width * roi_b.height; // Get the area of biggest element, at beginning it is same as "current" element

    if (ac > ab)
    {
        ib = ic;
        roi_b.x = guns[ib].x;
        roi_b.y = guns[ib].y;
        roi_b.width = (guns[ib].width);
        roi_b.height = (guns[ib].height);
    }

    Point pt1(guns[ic].x, guns[ic].y); // Display detected guns on main window - live stream from camera
    Point pt2((guns[ic].x + guns[ic].height), (guns[ic].y + guns[ic].width));

    //bbox = cvRect(roi_b.x, roi_b.y, roi_b.width, roi_b.height);
    //int counter = 0;

    rectangle(frame, pt1, pt2, Scalar(0, 0, 255), 2, 8, 0);   
    putText(frame, "Gun Detected!", pt1, FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0,250,250), 1, CV_AA);


    // if(gun detected)
    //counter = counter + 1;
    /*
    if(counter > 5)
    {
        turn on the LED of Raspberry Pi;
        counter = 0;
    }
    */

} //end of inner for loop

imshow("original", frame);
if(waitKey(30) >= 0) break;
} //end of outer for loop
return 0;
} //end main 

Solution

  • You have a lot of explicit code that can be brought down to single-line statements.

    ab = 0;
    for( ic=0; ic < guns.size(); ic++ )
    {
        roi_c = guns[i];
        if( roi_c.area() > ab )
        {
            roi_b = roi_c;
            ab = roi_c.area();
        }
    
        rectangle(frame, roi_c, Scalar(0, 0, 255), 2, 8, 0);
    }
    

    If you want to check if at least one gun is detected, you could write: if( guns.size() > 0 ) { .. }. If you want to check if the largest gun detected is larger than some threshold, you could go with something like if( roi_b.area() > some_threshold ).

    Hope this answers.