205 lines
7.7 KiB
C++
205 lines
7.7 KiB
C++
|
/*
|
|||
|
* @Descripttion:
|
|||
|
* @version:
|
|||
|
* @Author: tjk
|
|||
|
* @Date: 2023-01-31 17:01:02
|
|||
|
* @LastEditors: Please set LastEditors
|
|||
|
* @LastEditTime: 2023-02-01 17:04:12
|
|||
|
*/
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
#include <string>
|
|||
|
#include <opencv2/opencv.hpp>
|
|||
|
|
|||
|
using namespace std;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
typedef struct armor_point {
|
|||
|
cv::Point point;
|
|||
|
double dis;
|
|||
|
}armor_point;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
|||
|
void drawRotatedRect(cv::Mat& img, const cv::RotatedRect& rect, const cv::Scalar& color, int thickness)
|
|||
|
{
|
|||
|
cv::Point2f Vertex[4];
|
|||
|
rect.points(Vertex);
|
|||
|
for (int i = 0; i < 4; i++)
|
|||
|
{
|
|||
|
cv::line(img, Vertex[i], Vertex[(i + 1) % 4], color, thickness);
|
|||
|
}
|
|||
|
}
|
|||
|
double distance(cv::Point a, cv::Point b)
|
|||
|
{
|
|||
|
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int main()
|
|||
|
{
|
|||
|
//<2F><>ȡ<EFBFBD><C8A1>Ƶ<EFBFBD><C6B5>Դ
|
|||
|
string video_path ="./vedio/blue2.mp4";
|
|||
|
cv::VideoCapture cap;
|
|||
|
cap.open(video_path);
|
|||
|
|
|||
|
|
|||
|
// cv::VideoWriter writer;
|
|||
|
// int coder = cv::VideoWriter::fourcc('M','J','P','G');//ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
|||
|
// double fps=25.0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ֡<C6B5><D6A1>
|
|||
|
// string filename="live.avi";//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
// writer.open(filename,coder,fps,cv::Size(1350,1080),true);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>
|
|||
|
// if(!writer.isOpened()){
|
|||
|
// cout<<"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ļ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD><EFBFBD><EFBFBD>"<<endl;
|
|||
|
// return -1;
|
|||
|
// }
|
|||
|
|
|||
|
|
|||
|
while (true) {
|
|||
|
cv::Mat src_frame;
|
|||
|
cap >> src_frame;
|
|||
|
cv::resize(src_frame, src_frame, cv::Size(640, 480));
|
|||
|
//<2F><>ȡ<EFBFBD><C8A1>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD>¹涨<C2B9><E6B6A8><EFBFBD>ڴ<EFBFBD>С
|
|||
|
|
|||
|
vector<cv::Mat> bgr_images;
|
|||
|
cv::split(src_frame, bgr_images);
|
|||
|
cv::Mat b_src_img = bgr_images[0];
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫͨ<C9AB><CDA8><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ɫͨ<C9AB><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ģ<EFBFBD><C4A3>
|
|||
|
cv::blur(b_src_img, b_src_img, cv::Size(3, 3));
|
|||
|
//<2F><>ֵ<EFBFBD><D6B5>
|
|||
|
cv::Mat threshold_img;
|
|||
|
cv::threshold(b_src_img, threshold_img, 130, 255, cv::THRESH_BINARY);
|
|||
|
//Ѱ<><D1B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
vector<vector<cv::Point>> contours;
|
|||
|
cv::findContours(threshold_img, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
|
|||
|
cv::drawContours(src_frame,contours,-1,cv::Scalar(0,0,255));
|
|||
|
|
|||
|
cv::Point r_center; // R <20><><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
|
|||
|
vector<cv::RotatedRect> contours_min_rects;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
|
|||
|
vector<cv::RotatedRect> armor_min_rects;
|
|||
|
vector<cv::RotatedRect> target_min_rects;
|
|||
|
vector<cv::RotatedRect> r_min_rects; //R
|
|||
|
|
|||
|
int r_index = -1;
|
|||
|
// int cnt = 0;
|
|||
|
for (unsigned int contour_index = 0; contour_index < contours.size(); contour_index++) {
|
|||
|
// //Ѱ<><D1B0><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>,<2C>Ž<EFBFBD><C5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>㽫<EFBFBD><E3BDAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cv::RotatedRect minrect = minAreaRect(contours[contour_index]);
|
|||
|
cv::Rect rect = boundingRect(contours[contour_index]);
|
|||
|
|
|||
|
//<2F>ҵ<EFBFBD><D2B5><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
|||
|
if (minrect.size.area() <= 6000.0 && minrect.size.area() > 150) {
|
|||
|
float width;
|
|||
|
float height;
|
|||
|
//<2F>жϳ<D0B6><CFB3><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
|
|||
|
if (minrect.size.width > minrect.size.height) {
|
|||
|
width = minrect.size.width;
|
|||
|
height = minrect.size.height;
|
|||
|
}
|
|||
|
else {
|
|||
|
width = minrect.size.height;
|
|||
|
height = minrect.size.width;
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD>С<EFBFBD><D0A1>5 <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>Dz<EFBFBD><C7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD><52> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD>С<EFBFBD><D0A1>1.17 <20><>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD><52> ע<><D7A2><EFBFBD>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>λ<EFBFBD>ã<EFBFBD>
|
|||
|
if (width / height < 5) {
|
|||
|
contours_min_rects.push_back(minrect);
|
|||
|
if (minrect.size.area() > 200 && minrect.size.area() < 350 && minrect.center.y > 100) { // find R
|
|||
|
if (height / width > 0.85) {
|
|||
|
// R_minRects.push_back(minrect);
|
|||
|
r_center = minrect.center;
|
|||
|
cv::circle(src_frame, minrect.center, 15, cv::Scalar(5, 255, 100));
|
|||
|
r_index = contour_index;
|
|||
|
// std::cout<<cnt++<<std::endl;
|
|||
|
}
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD><D2BF>߱<EFBFBD>С<EFBFBD><D0A1>1.42 <20><>ôΪ<C3B4><CEAA>С<EFBFBD><D0A1>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
|||
|
else {
|
|||
|
if (minrect.size.area() > 300 && minrect.size.area() < 4350 && (height / width) < 0.7) {
|
|||
|
armor_min_rects.push_back(minrect);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
bool find_ok = false;
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
|
|||
|
for (int i = 0; i < armor_min_rects.size() - 1; i++) {
|
|||
|
for (int j = i + 1; j < armor_min_rects.size(); j++) {
|
|||
|
double dis = distance(armor_min_rects[i].center, armor_min_rects[j].center);
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>100 <20><>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ܵĻ<DCB5><C4BB><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (dis < 100) {
|
|||
|
target_min_rects.push_back(armor_min_rects[i]);
|
|||
|
target_min_rects.push_back(armor_min_rects[j]);
|
|||
|
find_ok = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
// std::cout<<dis<<std::endl;
|
|||
|
}
|
|||
|
if (find_ok) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD> <20><>ô<EFBFBD><C3B4><EFBFBD>½<EFBFBD><C2BD><EFBFBD>whileѭ<65><D1AD>
|
|||
|
if (target_min_rects.size() != 2) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
else {
|
|||
|
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ζ<EFBFBD>Ӧ<EFBFBD>ĵ<EFBFBD> <20>ɴ<EFBFBD><C9B4>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>ĵ<EFBFBD>
|
|||
|
cv::RotatedRect rrect_in; //= target_minRects[0];
|
|||
|
cv::RotatedRect rrect_out;// = target_minRects[1];
|
|||
|
double dis1 = distance(r_center, target_min_rects[0].center);
|
|||
|
double dis2 = distance(r_center, target_min_rects[1].center);
|
|||
|
if (dis1 > dis2) {
|
|||
|
rrect_in = target_min_rects[1];
|
|||
|
rrect_out = target_min_rects[0];
|
|||
|
}
|
|||
|
else {
|
|||
|
rrect_in = target_min_rects[0];
|
|||
|
rrect_out = target_min_rects[1];
|
|||
|
}
|
|||
|
drawRotatedRect(src_frame, rrect_in, cv::Scalar(0, 250, 0), 1);
|
|||
|
drawRotatedRect(src_frame, rrect_out, cv::Scalar(0, 0, 255), 1);
|
|||
|
|
|||
|
cv::Point target_center = cv::Point((int)((rrect_in.center.x + rrect_out.center.x) / 2), (int)((rrect_in.center.y + rrect_out.center.y) / 2));
|
|||
|
cv::circle(src_frame, target_center, 5, cv::Scalar(0, 0, 255), -1);
|
|||
|
cv::Point2f in_vet_points[4];
|
|||
|
cv::Point2f out_vet_points[4];
|
|||
|
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>е<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵľ<C4B5><C4BE><EFBFBD>
|
|||
|
rrect_in.points(in_vet_points);
|
|||
|
rrect_out.points(out_vet_points);
|
|||
|
vector<armor_point> armor_points;
|
|||
|
for (int i = 0; i < 4; i++) {
|
|||
|
armor_point point;
|
|||
|
point.point = in_vet_points[i];
|
|||
|
point.dis = distance(target_center, in_vet_points[i]);
|
|||
|
armor_points.push_back(point);
|
|||
|
}
|
|||
|
for (int i = 0; i < 4; i++) {
|
|||
|
armor_point point;
|
|||
|
point.point = out_vet_points[i];
|
|||
|
point.dis = distance(target_center, out_vet_points[i]);
|
|||
|
armor_points.push_back(point);
|
|||
|
}
|
|||
|
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>
|
|||
|
sort(armor_points.begin(), armor_points.end(), [](armor_point a, armor_point b) {return a.dis < b.dis; });
|
|||
|
for (int i = 0; i < 4; i++)
|
|||
|
{
|
|||
|
cv::circle(src_frame, armor_points[i].point, 3, cv::Scalar(255, 0, 255), -1);
|
|||
|
}
|
|||
|
int buff_run_radius = (int)distance(r_center, target_center);
|
|||
|
cv::circle(src_frame, r_center, buff_run_radius, cv::Scalar(55, 110, 255), 1);
|
|||
|
}
|
|||
|
// cv::resize(src_frame,src_frame,cv::Size(1350,1080));
|
|||
|
// writer.write(src_frame);//<2F><>ͼ<EFBFBD><CDBC>д<EFBFBD><D0B4><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>
|
|||
|
cv::imshow("src_img", src_frame);
|
|||
|
cv::imshow("threshold_img",threshold_img);
|
|||
|
if (cv::waitKey(0) == 'q') {
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
// writer.release();
|
|||
|
cap.release();
|
|||
|
return 0;
|
|||
|
}
|