demo/2023816/test.cpp

205 lines
7.7 KiB
C++
Raw Normal View History

2023-10-08 22:10:52 +08:00
/*
* @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;
}