基于OpenCV实现的物体定位系统OpenCV是一个很强大的机器视觉库,利用它我们可以开发出丰富多彩的使用项目。
近日,我在研究一个图中物体定位系统。
本程序用的是OpenCV2.4.9,附带OpenCV3.0。
程序中的原图为我随手拍的一张图片图中有三个物体,都是蓝色的,我首先取原图的蓝色通道变为灰度图灰度图经过中值滤波后可以得到去噪后的图片根据原图的蓝色通道和红色通道的大概取值范围,我们可得到比较满意的二值图为了去掉物体中少量的黑色部分,我用闭运算然而,图中最上面的那个物体里面还有一块很大的黑色(目前我也不知道怎么去掉,如果有大神知道望告知~~)接下来就是找出物体的轮廓最后找到能包围轮廓的最小矩形好了,占时就这么多了下面是配套的程序OpenCV2.4.9半根[cpp]view plain copy1.#include<opencv2\opencv.hpp>2.#include<iostream>3.#define BIN_DIV 1104.ing namespace std;ing namespace cv;7.8.int main()9.{10. Mat srcImg, midImg, dstImg;11. srcImg = imread("hehe.jpg");12. Mat xianshi = srcImg.clone();13. Mat redChannel;14. namedWindow("【原图】", WINDOW_NORMAL);15. imshow("【原图】", srcImg);16. Mat grayImg;17. vector<Mat> channels;18. split(srcImg, channels);19.//cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);20. grayImg = channels.at(0);21. redChannel = channels.at(2);22. namedWindow("【灰度图】", WINDOW_NORMAL);24.//均值滤波25. blur(grayImg, grayImg, Size(20, 20), Point(-1, -1));26. namedWindow("【均值滤波后】", WINDOW_NORMAL);27. imshow("【均值滤波后】", grayImg);28.//转化为二值图29. Mat midImg1 = grayImg.clone();30.int rowNumber = midImg1.rows;31.int colNumber = midImg1.cols;32.33.for (int i = 0; i<rowNumber; i++)34. {35. uchar* data = midImg1.ptr<uchar>(i); //取第i行的首地址36. uchar* redData = redChannel.ptr<uchar>(i);37.for (int j = 0; j<colNumber; j++)38. {39.if (data[j]>BIN_DIV&&redData[j]<BIN_DIV *2/ 3)40. data[j] = 255;41.else42. data[j] = 0;43. }44. }45. namedWindow("【二值图】", WINDOW_NORMAL);46. imshow("【二值图】", midImg1);47. Mat midImg2 = midImg1.clone();48. Mat element = getStructuringElement(MORPH_RECT, Size(40, 40));49. morphologyEx(midImg1, midImg2, MORPH_CLOSE, element);50. namedWindow("【闭运算后】", WINDOW_NORMAL);51. imshow("【闭运算后】", midImg2);52. cout << "midImg1.channel=" << midImg1.channels() << endl;53. cout << "mdiImg1.depth" << midImg1.depth() << endl;54.//查找图像轮廓55. Mat midImg3 = Mat::zeros(midImg2.rows, midImg2.cols, CV_8UC3);56. vector<vector<Point>> contours;57. vector<Vec4i> hierarchy;58. findContours(midImg2, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);59.int index = 0;60.for (; index >= 0; index = hierarchy[index][0])61. {62. Scalar color(255, 255, 255);63. drawContours(midImg3, contours, index, color, NULL, 8, hierarchy);64. }65. namedWindow("【轮廓图】", WINDOW_NORMAL);67. Mat midImg4 = midImg3.clone();68.//创建包围轮廓的矩形边界69.for (int i = 0; i<contours.size(); i++)70. {71.//每个轮廓72. vector<Point> points = contours[i];73.//对给定的2D点集,寻找最小面积的包围矩形74. RotatedRect box = minAreaRect(Mat(points));75. Point2f vertex[4];76. box.points(vertex);77.//绘制出最小面积的包围矩形78. line(xianshi, vertex[0], vertex[1], Scalar(100, 200, 211), 6, CV_AA);79. line(xianshi, vertex[1], vertex[2], Scalar(100, 200, 211), 6, CV_AA);80. line(xianshi, vertex[2], vertex[3], Scalar(100, 200, 211), 6, CV_AA);81. line(xianshi, vertex[3], vertex[0], Scalar(100, 200, 211), 6, CV_AA);82.//绘制中心的光标83. Point s1, l, r, u, d;84. s1.x = (vertex[0].x + vertex[2].x) / 2.0;85. s1.y = (vertex[0].y + vertex[2].y) / 2.0;86. l.x = s1.x - 10;87. l.y = s1.y;88.89. r.x = s1.x + 10;90. r.y = s1.y;91.92. u.x = s1.x;93. u.y = s1.y - 10;94.95. d.x = s1.x;96. d.y = s1.y + 10;97. line(xianshi, l, r, Scalar(100, 200, 211), 2, CV_AA);98. line(xianshi, u, d, Scalar(100, 200, 211), 2, CV_AA);99. }100. namedWindow("【绘制的最小面积矩形】", WINDOW_NORMAL);101. imshow("【绘制的最小面积矩形】", xianshi);102. waitKey(0);103.return 0;104.}OpenCV3.0版本[cpp]view plain copy1.#include<opencv2\opencv.hpp>2.#include<iostream>3.#define BIN_DIV 1204.ing namespace std;ing namespace cv;7.8.int main()9.{10. Mat srcImg=imread("haha.jpg");11. Mat xianshi=srcImg.clone();12. Mat redChannel;13. namedWindow("【原图】",WINDOW_NORMAL);14. imshow("【原图】",srcImg);15. Mat grayImg;16. vector<Mat> channels;17. split(srcImg,channels);18.//cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);19. grayImg=channels.at(0);20. redChannel=channels.at(2);21. namedWindow("【灰度图】",WINDOW_NORMAL);22. imshow("【灰度图】",grayImg);23.//均值滤波24. blur(grayImg,grayImg,Size(20,20),Point(-1,-1));25. namedWindow("【均值滤波后】",WINDOW_NORMAL);26. imshow("【均值滤波后】",grayImg);27.//转化为二值图28. Mat midImg1=grayImg.clone();29.int rowNumber=midImg1.rows;30.int colNumber=midImg1.cols;31.32.for(int i=0;i<rowNumber;i++)33. {34. uchar* data=midImg1.ptr<uchar>(i); //取第i行的首地址35. uchar* redData=redChannel.ptr<uchar>(i);36.for(int j=0;j<colNumber;j++)37. {38.if(data[j]>BIN_DIV&&redData[j]<BIN_DIV/2)39. data[j]=0;40.else41. data[j]=255;42. }43. }44. namedWindow("【二值图】",WINDOW_NORMAL);45. imshow("【二值图】",midImg1);46. Mat midImg2=midImg1.clone();47. Mat element=getStructuringElement(MORPH_RECT,Size(20,20));48. morphologyEx(midImg1,midImg2,MORPH_OPEN,element);49. namedWindow("【开运算后】",WINDOW_NORMAL);50. imshow("【开运算后】",midImg2);51. cout<<"midImg1.channel="<<midImg1.channels()<<endl;52. cout<<"mdiImg1.depth"<<midImg1.depth()<<endl;53.//查找图像轮廓54. Mat midImg3=Mat::zeros(midImg2.rows,midImg2.cols,CV_8UC3);55. vector<vector<Point>> contours;56. vector<Vec4i> hierarchy;57. findContours(midImg2,contours,hierarchy,RETR_CCOMP,CHAIN_APPROX_SIMPLE);58.int index=0;59.for(;index>=0;index=hierarchy[index][0])60. {61. Scalar color(255,255,255);62. drawContours(midImg3,contours,index,color,NULL,8,hierarchy);63. }64. namedWindow("【轮廓图】",WINDOW_NORMAL);65. imshow("【轮廓图】",midImg3);66. Mat midImg4=midImg3.clone();67.//创建包围轮廓的矩形边界68.for(int i=0;i<contours.size();i++)69. {70.//每个轮廓71. vector<Point> points=contours[i];72.//对给定的2D点集,寻找最小面积的包围矩形73. RotatedRect box=minAreaRect(Mat(points));74. Point2f vertex[4];75. box.points(vertex);76.//绘制出最小面积的包围矩形77. line(xianshi,vertex[0],vertex[1],Scalar(100,200,211),6,LINE_AA);78. line(xianshi,vertex[1],vertex[2],Scalar(100,200,211),6,LINE_AA);79. line(xianshi,vertex[2],vertex[3],Scalar(100,200,211),6,LINE_AA);80. line(xianshi,vertex[3],vertex[0],Scalar(100,200,211),6,LINE_AA);81.//绘制中心的光标82. Point s1,l,r,u,d;83. s1.x=(vertex[0].x+vertex[2].x)/2.0;84. s1.y=(vertex[0].y+vertex[2].y)/2.0;85. l.x=s1.x-10;86. l.y=s1.y;87.88. r.x=s1.x+10;89. r.y=s1.y;90.91. u.x=s1.x;92. u.y=s1.y-10;93.94. d.x=s1.x;95. d.y=s1.y+10;96. line(xianshi,l,r,Scalar(100,200,211),2,LINE_AA);97. line(xianshi,u,d,Scalar(100,200,211),2,LINE_AA);98. }99. namedWindow("【绘制的最小面积矩形】",WINDOW_NORMAL); 100. imshow("【绘制的最小面积矩形】",xianshi);101. waitKey(0);102.return 0;103.}。