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
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.