基于opencv的物体定位
2016-08-17 20:44
330 查看
opencv是一个很强大的机器视觉库,利用它我们可以开发出丰富多彩的使用项目。近日,我在研究一个图中物体定位系统。本程序用的是OpenCV2.4.9,附带OpenCV3.0。
程序中的原图为我随手拍的一张图片
图中有三个物体,都是蓝色的,我首先取原图的蓝色通道变为灰度图
灰度图经过中值滤波后可以得到去噪后的图片
根据原图的蓝色通道和红色通道的大概取值范围,我们可得到比较满意的二值图
为了去掉物体中少量的黑色部分,我用闭运算
然而,图中最上面的那个物体里面还有一块很大的黑色(目前我也不知道怎么去掉,如果有大神知道望告知~~)
接下来就是找出物体的轮廓
最后找到能包围轮廓的最小矩形
好了,占时就这么多了
下面是配套的程序
OpenCV2.4.9半根
OpenCV3.0版本
程序中的原图为我随手拍的一张图片
图中有三个物体,都是蓝色的,我首先取原图的蓝色通道变为灰度图
灰度图经过中值滤波后可以得到去噪后的图片
根据原图的蓝色通道和红色通道的大概取值范围,我们可得到比较满意的二值图
为了去掉物体中少量的黑色部分,我用闭运算
然而,图中最上面的那个物体里面还有一块很大的黑色(目前我也不知道怎么去掉,如果有大神知道望告知~~)
接下来就是找出物体的轮廓
最后找到能包围轮廓的最小矩形
好了,占时就这么多了
下面是配套的程序
OpenCV2.4.9半根
#include<opencv2\opencv.hpp> #include<iostream> #define BIN_DIV 110 using namespace std; using namespace cv; int main() { Mat srcImg, midImg, dstImg; srcImg = imread("hehe.jpg"); Mat xianshi = srcImg.clone(); Mat redChannel; namedWindow("【原图】", WINDOW_NORMAL); imshow("【原图】", srcImg); Mat grayImg; vector<Mat> channels; split(srcImg, channels); //cvtColor(srcImg,grayImg,COLOR_BGR2GRAY); grayImg = channels.at(0); redChannel = channels.at(2); namedWindow("【灰度图】", WINDOW_NORMAL); imshow("【灰度图】", grayImg); //均值滤波 blur(grayImg, grayImg, Size(20, 20), Point(-1, -1)); namedWindow("【均值滤波后】", WINDOW_NORMAL); imshow("【均值滤波后】", grayImg); //转化为二值图 Mat midImg1 = grayImg.clone(); int rowNumber = midImg1.rows; int colNumber = midImg1.cols; for (int i = 0; i<rowNumber; i++) { uchar* data = midImg1.ptr<uchar>(i); //取第i行的首地址 uchar* redData = redChannel.ptr<uchar>(i); for (int j = 0; j<colNumber; j++) { if (data[j]>BIN_DIV&&redData[j]<BIN_DIV *2/ 3) data[j] = 255; else data[j] = 0; } } namedWindow("【二值图】", WINDOW_NORMAL); imshow("【二值图】", midImg1); Mat midImg2 = midImg1.clone(); Mat element = getStructuringElement(MORPH_RECT, Size(40, 40)); morphologyEx(midImg1, midImg2, MORPH_CLOSE, element); namedWindow("【闭运算后】", WINDOW_NORMAL); imshow("【闭运算后】", midImg2); cout << "midImg1.channel=" << midImg1.channels() << endl; cout << "mdiImg1.depth" << midImg1.depth() << endl; //查找图像轮廓 Mat midImg3 = Mat::zeros(midImg2.rows, midImg2.cols, CV_8UC3); vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(midImg2, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE); int index = 0; for (; index >= 0; index = hierarchy[index][0]) { Scalar color(255, 255, 255); drawContours(midImg3, contours, index, color, NULL, 8, hierarchy); } namedWindow("【轮廓图】", WINDOW_NORMAL); imshow("【轮廓图】", midImg3); Mat midImg4 = midImg3.clone(); //创建包围轮廓的矩形边界 for (int i = 0; i<contours.size(); i++) { //每个轮廓 vector<Point> points = contours[i]; //对给定的2D点集,寻找最小面积的包围矩形 RotatedRect box = minAreaRect(Mat(points)); Point2f vertex[4]; box.points(vertex); //绘制出最小面积的包围矩形 line(xianshi, vertex[0], vertex[1], Scalar(100, 200, 211), 6, CV_AA); line(xianshi, vertex[1], vertex[2], Scalar(100, 200, 211), 6, CV_AA); line(xianshi, vertex[2], vertex[3], Scalar(100, 200, 211), 6, CV_AA); line(xianshi, vertex[3], vertex[0], Scalar(100, 200, 211), 6, CV_AA); //绘制中心的光标 Point s1, l, r, u, d; s1.x = (vertex[0].x + vertex[2].x) / 2.0; s1.y = (vertex[0].y + vertex[2].y) / 2.0; l.x = s1.x - 10; l.y = s1.y; r.x = s1.x + 10; r.y = s1.y; u.x = s1.x; u.y = s1.y - 10; d.x = s1.x; d.y = s1.y + 10; line(xianshi, l, r, Scalar(100, 200, 211), 2, CV_AA); line(xianshi, u, d, Scalar(100, 200, 211), 2, CV_AA); } namedWindow("【绘制的最小面积矩形】", WINDOW_NORMAL); imshow("【绘制的最小面积矩形】", xianshi); waitKey(0); return 0; }
OpenCV3.0版本
#include<opencv2\opencv.hpp> #include<iostream> #define BIN_DIV 120 using namespace std; using namespace cv; int main() { Mat srcImg=imread("haha.jpg"); Mat xianshi=srcImg.clone(); Mat redChannel; namedWindow("【原图】",WINDOW_NORMAL); imshow("【原图】",srcImg); Mat grayImg; vector<Mat> channels; split(srcImg,channels); //cvtColor(srcImg,grayImg,COLOR_BGR2GRAY); grayImg=channels.at(0); redChannel=channels.at(2); namedWindow("【灰度图】",WINDOW_NORMAL); imshow("【灰度图】",grayImg); //均值滤波 blur(grayImg,grayImg,Size(20,20),Point(-1,-1)); namedWindow("【均值滤波后】",WINDOW_NORMAL); imshow("【均值滤波后】",grayImg); //转化为二值图 Mat midImg1=grayImg.clone(); int rowNumber=midImg1.rows; int colNumber=midImg1.cols; for(int i=0;i<rowNumber;i++) { uchar* data=midImg1.ptr<uchar>(i); //取第i行的首地址 uchar* redData=redChannel.ptr<uchar>(i); for(int j=0;j<colNumber;j++) { if(data[j]>BIN_DIV&&redData[j]<BIN_DIV/2) data[j]=0; else data[j]=255; } } namedWindow("【二值图】",WINDOW_NORMAL); imshow("【二值图】",midImg1); Mat midImg2=midImg1.clone(); Mat element=getStructuringElement(MORPH_RECT,Size(20,20)); morphologyEx(midImg1,midImg2,MORPH_OPEN,element); namedWindow("【开运算后】",WINDOW_NORMAL); imshow("【开运算后】",midImg2); cout<<"midImg1.channel="<<midImg1.channels()<<endl; cout<<"mdiImg1.depth"<<midImg1.depth()<<endl; //查找图像轮廓 Mat midImg3=Mat::zeros(midImg2.rows,midImg2.cols,CV_8UC3); vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(midImg2,contours,hierarchy,RETR_CCOMP,CHAIN_APPROX_SIMPLE); int index=0; for(;index>=0;index=hierarchy[index][0]) { Scalar color(255,255,255); drawContours(midImg3,contours,index,color,NULL,8,hierarchy); } namedWindow("【轮廓图】",WINDOW_NORMAL); imshow("【轮廓图】",midImg3); Mat 4000 midImg4=midImg3.clone(); //创建包围轮廓的矩形边界 for(int i=0;i<contours.size();i++) { //每个轮廓 vector<Point> points=contours[i]; //对给定的2D点集,寻找最小面积的包围矩形 RotatedRect box=minAreaRect(Mat(points)); Point2f vertex[4]; box.points(vertex); //绘制出最小面积的包围矩形 line(xianshi,vertex[0],vertex[1],Scalar(100,200,211),6,LINE_AA); line(xianshi,vertex[1],vertex[2],Scalar(100,200,211),6,LINE_AA); line(xianshi,vertex[2],vertex[3],Scalar(100,200,211),6,LINE_AA); line(xianshi,vertex[3],vertex[0],Scalar(100,200,211),6,LINE_AA); //绘制中心的光标 Point s1,l,r,u,d; s1.x=(vertex[0].x+vertex[2].x)/2.0; s1.y=(vertex[0].y+vertex[2].y)/2.0; l.x=s1.x-10; l.y=s1.y; r.x=s1.x+10; r.y=s1.y; u.x=s1.x; u.y=s1.y-10; d.x=s1.x; d.y=s1.y+10; line(xianshi,l,r,Scalar(100,200,211),2,LINE_AA); line(xianshi,u,d,Scalar(100,200,211),2,LINE_AA); } namedWindow("【绘制的最小面积矩形】",WINDOW_NORMAL); imshow("【绘制的最小面积矩形】",xianshi); waitKey(0); return 0; }
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- Android Studio中配置OpenCV库开发环境的教程
- 基于C++实现kinect+opencv 获取深度及彩色数据
- visual studio 2012安装配置方法图文教程 附opencv配置教程
- OpenCV 2.4.3 C++ 平滑处理分析
- Python中使用OpenCV库来进行简单的气象学遥感影像计算
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- Python环境搭建之OpenCV的步骤方法
- Python+Opencv识别两张相似图片
- Python实现OpenCV的安装与使用示例
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程
- opencv-python学习一--人脸检测
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- 使用 Java 开发 OpenCV 应用
- OpenCV配置,从来没有这么简单!
- ubuntu下opencv和qt的安装配置
- visual studio 2012安装配置方法图文教程 附opencv配置教程