目标相对位置(返回角度和距离).md

  1. //代码为矿大大疆创新实验室比赛时所写,copy一份
  2. #include <iostream>
  3. #include "opencv2/opencv.hpp"
  4. #include "opencv2/imgproc/imgproc.hpp"
  5. #include "opencv2/core/core.hpp"
  6. #include<stdio.h>
  7. #include<math.h>
  8. #define IMAGE_WIDTH 640 //图像宽度
  9. #define IMAGE_HEIGHT 480 //图像高度
  10. #define pi 3.14159265 //图像高度
  11. using namespace cv;
  12. using namespace std;
  13. int main( int argc, char** argv )
  14. {
  15. // VideoCapture cap("2.avi");
  16. VideoCapture cap(0);
  17. if ( !cap.isOpened() )
  18. {
  19. cout << "Cannot open" << endl;
  20. return -1;
  21. }
  22. /***************HSV设置滑动块*************************/
  23. int iLowH = 90;
  24. int iHighH = 110;
  25. int iLowS = 90;
  26. int iHighS = 255;
  27. int iLowV = 90;
  28. int iHighV = 255;
  29. namedWindow("Control", CV_WINDOW_AUTOSIZE); //建立调整HSV的窗口"Control"
  30. cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
  31. cvCreateTrackbar("HighH", "Control", &iHighH, 179);
  32. cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
  33. cvCreateTrackbar("HighS", "Control", &iHighS, 255);
  34. cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
  35. cvCreateTrackbar("HighV", "Control", &iHighV, 255);
  36. /*************************************************/
  37. //Size s(640, 480);
  38. //VideoWriter writer=VideoWriter("imgThresholded.avi",CV_FOURCC('M','J','P','G'), 25, s);//写视频
  39. //对视频处理并显示
  40. while (true)
  41. {
  42. Mat imgOriginal;
  43. bool bSuccess = cap.read(imgOriginal); // 从视频中读取一帧存入矩阵imgOriginal,并检验是否为空
  44. if (!bSuccess) //imgOriginal为空,跳出循环
  45. {
  46. cout << "Cannot read a frame from video stream" << endl;
  47. break;
  48. }
  49. /*******************选取目标,与背景分离********************/
  50. Mat imgHSV;
  51. vector<Mat> hsvSplit;
  52. cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //取视频的一帧 从BGR 转换到HSV
  53. //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做
  54. split(imgHSV, hsvSplit);
  55. equalizeHist(hsvSplit[2],hsvSplit[2]);
  56. merge(hsvSplit,imgHSV);
  57. Mat imgThresholded;
  58. //检查imgHSV每一个像素,在Scalar(iLowH, iLowS, iLowV)和Scalar(iHighH, iHighS, iHighV)之间就设置为255,并保存在 imgThresholded图像中,否则为0。
  59. inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);
  60. //开操作 (去除一些噪点)
  61. Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
  62. morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element);
  63. //闭操作 (连接一些连通域,消除一些空洞)
  64. morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element);
  65. /*************************************************************/
  66. int sum=0;
  67. for( int i = 0; i < imgThresholded.rows; ++i)
  68. {
  69. //获取第 i 行首像素指针
  70. uchar * p = imgThresholded.ptr<uchar>(i);
  71. //对第 i 行的每个像素(byte)操作
  72. for( int j = 0; j < imgThresholded.cols; ++j )
  73. {
  74. sum+=p[j];
  75. }
  76. }
  77. if(sum>0) //判断imgThresholded是否为空
  78. {
  79. /*********************多目标的选取*****************************/
  80. //定义轮廓和层次结构
  81. vector<vector<Point> > contours;
  82. vector<Vec4i> hierarchy;
  83. //查找轮廓
  84. findContours( imgThresholded, contours, hierarchy,RETR_EXTERNAL, CHAIN_APPROX_NONE );
  85. int area, index = 0;
  86. int maxIndex=0;
  87. int maxArea = 10;
  88. //遍历所有轮廓,判断最大轮廓
  89. for( ; index >= 0; index = hierarchy[index][0] )
  90. {
  91. area = fabs(contourArea(contours[index]));
  92. if(area > maxArea)
  93. {
  94. maxIndex=index;
  95. maxArea = area;
  96. //printf("max area == %i\n", maxArea);
  97. }
  98. Scalar color(255, 255, 255 );
  99. drawContours(imgThresholded, contours, index, color, CV_FILLED, 8, hierarchy );//对轮廓内部着色
  100. }
  101. /*************************************************************/
  102. // writer << imgThresholded;
  103. /*********************圈定敌方的位置****************************/
  104. vector<Point> points;//点值
  105. points=contours[maxIndex];
  106. //对给定的 2D 点集,寻找最小面积的包围矩形
  107. Point2f vertex[4];
  108. RotatedRect box = minAreaRect(Mat(points));
  109. box.points(vertex);
  110. /******目标像素位置******/
  111. Point2f target=(vertex[0]+vertex[2])*0.5;
  112. //己方到目标的向量
  113. line(imgOriginal, (vertex[0]+vertex[2])*0.5,Point(IMAGE_WIDTH*0.5,IMAGE_HEIGHT), Scalar(0, 255, 0), 2, CV_AA);
  114. /****************坐标转换*********************/
  115. Mat intrinsic_matrix=(Mat_<float>(3,3) << 797.64461,0, 341.87424,0,797.70292,282.35509, 0, 0, 1);
  116. Mat rotation_tanslation_matrix=(Mat_<float>(3,3) << 0.021766,0.999506,-88.259736,-0.009815,0.022903,144.411487,-0.999715,0.021537,860.462175);
  117. Mat fundamental_matrix= intrinsic_matrix*rotation_tanslation_matrix;
  118. fundamental_matrix=fundamental_matrix.inv();
  119. Mat target3D(3,1,CV_8UC1);
  120. Mat target2D=(Mat_<float>(3,1) <<target.x,target.y,1 );
  121. target3D= fundamental_matrix*target2D;
  122. //目标世界坐标
  123. float X = target3D.at<float>(0,0)/target3D.at<float>(2,0);
  124. float Y = target3D.at<float>(1,0)/target3D.at<float>(2,0);
  125. // //显示世界坐标
  126. // char XText[128],YText[128];
  127. // snprintf(XText, sizeof(XText), "%f", X);
  128. // snprintf(YText, sizeof(YText), "%f", Y);
  129. // putText(imgOriginal,XText,Point(100,90),FONT_HERSHEY_SCRIPT_SIMPLEX, 1,Scalar(0,0,255), 3, 8);
  130. // putText(imgOriginal,YText,Point(400,90),FONT_HERSHEY_SCRIPT_SIMPLEX, 1,Scalar(0,0,255), 3, 8);
  131. Point2f cameraPos=Point(950,150);//相机世界坐标
  132. /******************************************/
  133. target=target-Point2f(IMAGE_WIDTH*0.5,IMAGE_HEIGHT);
  134. float angle=-atan(target.x/target.y)*180/pi;
  135. float distance=sqrt((cameraPos.x-X)*(cameraPos.x-X)+(cameraPos.y-Y)*(cameraPos.y-Y));
  136. char angleText[128],distanceText[128];
  137. snprintf(angleText, sizeof(angleText), "%f", angle);
  138. snprintf(distanceText, sizeof(distanceText), "%f", distance);
  139. //将数字绘到画面上
  140. putText(imgOriginal,angleText,Point(100,30),FONT_HERSHEY_SCRIPT_SIMPLEX, 1,Scalar(0,0,255), 3, 8);
  141. putText(imgOriginal,distanceText,Point(400,30),FONT_HERSHEY_SCRIPT_SIMPLEX, 1,Scalar(0,0,255), 3, 8);
  142. //绘制出最小面积的包围矩形
  143. for( int i = 0; i < 4; i++ )
  144. line(imgOriginal, vertex[i], vertex[(i+1)%4], Scalar(100, 200, 211), 2, CV_AA);
  145. /*************************************************/
  146. }
  147. else
  148. {
  149. putText(imgOriginal,"Looking for the enemy.......",Point(90,90),FONT_HERSHEY_PLAIN, 2,Scalar(0,0,255), 2, 8);
  150. }
  151. imshow("Original", imgOriginal); //原始图片
  152. imshow("Thresholded Image", imgThresholded); //二值化图片
  153. char key = (char) waitKey(50);
  154. if(key == 27) //esc键退出
  155. break;
  156. }
  157. return 0;
  158. }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值