RM视觉组新手,现在写的这个代码暂时不考虑运行效率。
ubuntu18.04 + qt5.11 + opencv-4.2.0
sudo apt-get install gpick
VideoCapture cap;
cap.open("/home/husonghui/C_plus_practice/march_partice/detect_energe/red-black.avi");
if(!cap.isOpened()){
cout << "fail to load!" << endl;
return -1;
}
Mat frame;
while(1){
cap >> frame;
if(frame.empty())
break;
...
...
}
Mat hsv = frame.clone();
frame.convertTo(frame,CV_32FC3,1.0/255,0);
cvtColor(frame,hsv,COLOR_BGR2HSV);
h(色相) | s(饱和度) | v(亮度值) | |
---|---|---|---|
外灯条 | 6 | 84 | 96 |
6 | 86 | 96 | |
5 | 87 | 93 | |
4 | 93 | 87 | |
5 | 92 | 80 | |
4 | 91 | 87 | |
被击打后的流水灯 | 43 | 57 | 100 |
39 | 57 | 100 | |
43 | 58 | 100 | |
39 | 60 | 100 | |
40 | 60 | 100 | |
42 | 54 | 100 |
根据数据,再转换一下,得到范围内的最大最小,并进行二值化处理
double low_H = 3;
double low_S = 0.55;
double low_V = 0.9;
double high_H = 40;
double high_S = 0.93;
double high_V = 1;
Mat hsv = frame.clone();
inRange(hsv,Scalar(low_H,low_S,low_V),Scalar(high_H,high_S,high_V),frame_threshold);
看一下效果,打击前后的边缘都存在断线。
4. 目标装甲轮廓识别及定位:
Mat kernel = getStructuringElement(cv::MORPH_RECT,Size(3,3));
dilate(frame_threshold,frame_threshold,kernel,Point(-1,-1),2);
morphologyEx(frame_threshold,frame_threshold,MORPH_CLOSE,kernel,Point(-1,-1),4);
处理之后,轮廓继承关系就很明显了(存在父轮廓,无同级轮廓和子轮廓的就是目标装甲的轮廓)
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Scalar color(0,255,0);
Point2f point_dete_center; //保存 RotatedRect类 返回的中心点坐标
findContours(frame_threshold,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE);
for(int i = 0; i != contours.size(); ++i){
if(hierarchy[i][3] != -1 && hierarchy[i][2] == -1 && hierarchy[i][1] == -1 && hierarchy[i][0] == -1){
drawContours(frame,contours,i,color,4,8);
RotatedRect rect_tmp = minAreaRect(contours[i]);
point_dete_center = rect_tmp.center;
if(LeastSquaresCircleFitting(vec_collect,centroid,radius)){
circle(frame,centroid,radius,Scalar(150,150,150),2,8);
}
再通过目标装甲的位置和圆心加上一个半径
line(frame,p_1,point_dete_center,Scalar(255,0,0),4);
int main()
{
VideoCapture cap;
cap.open("/home/husonghui/C_plus_practice/march_partice/detect_energe/red-black.avi");
if(!cap.isOpened()){
cout << "fail to load!" << endl;
return -1;
}
Mat frame;
vector<Point2d> vec_collect;
double radius;
Point2d centroid;
while(1){
cap >> frame;
if(frame.empty())
break;
Mat hsv = frame.clone();
Mat frame_threshold = frame.clone();
frame.convertTo(frame,CV_32FC3,1.0/255,0);
cvtColor(frame,hsv,COLOR_BGR2HSV);
double low_H = 3;
double low_S = 0.55;
double low_V = 0.9;
double high_H = 40;
double high_S = 0.93;
double high_V = 1;
inRange(hsv,Scalar(low_H,low_S,low_V),Scalar(high_H,high_S,high_V),frame_threshold);
Mat kernel = getStructuringElement(cv::MORPH_RECT,Size(3,3));
dilate(frame_threshold,frame_threshold,kernel,Point(-1,-1),2);
morphologyEx(frame_threshold,frame_threshold,MORPH_CLOSE,kernel,Point(-1,-1),4);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Scalar color(0,255,0);
Point2f point_dete_center; //保存 RotatedRect类 返回的中心点坐标
findContours(frame_threshold,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE);
for(int i = 0; i != contours.size(); ++i){
if(hierarchy[i][3] != -1 && hierarchy[i][2] == -1 && hierarchy[i][1] == -1 && hierarchy[i][0] == -1){
drawContours(frame,contours,i,color,4,8);
RotatedRect rect_tmp = minAreaRect(contours[i]);
point_dete_center = rect_tmp.center;
vec_collect.emplace_back(rect_tmp.center);
if(LeastSquaresCircleFitting(vec_collect,centroid,radius)){
circle(frame,centroid,radius,Scalar(150,150,150),2,8);
}
}
}
line(frame,centroid,point_dete_center,Scalar(255,0,0),4);
namedWindow("threshold",WINDOW_AUTOSIZE);
imshow("threshold",frame);
waitKey(1);
}
destroyAllWindows();
return 0;
}