注意:该程序功能是检测二维码,不是识别,只是在图中定出二维码的位置即可
原图是这样:如果出现这张图片时,程序需要找到二维码
![这里写图片描述](https://img-blog.csdn.net/20170208002256121?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhaXBwMDYwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
其余图片是这样:
![这里写图片描述](https://img-blog.csdn.net/20170208002356685?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhaXBwMDYwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
程序步骤:
1.图片缩小
2.灰度化,直方图均衡化,对比度增强,滤波
3.otsu阈值分割
4.五次膨胀
5.轮廓查找,如果轮廓满足一下条件,认为可能为二维码区域,像素面积大于60,长短轴之比小于1.3
6.对疑似区域做判断,因为本实验二维码贴在大概中心位置,找到疑似轮廓的质心,判断质心是不是在图片长宽的三分之一到三分之二之间,如果是认为是二维码区域
7.对二维码区域画成蓝色
#include <stdio.h>
#include <opencv/highgui.h>
#include <time.h>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
Mat srcImage;
Mat resizeImage;
Mat grayImage;
Mat equalizeHistImage;
Mat contrastandbrightImage;
Mat sobelImage;
Mat thresholdImage;
Mat dilateImage;
Mat areaImage;
Mat ellipseImage;
srcImage = imread("3.jpg");
Size dsize = Size(srcImage.cols*0.3,srcImage.rows*0.3);
resize(srcImage, resizeImage,dsize);
cvtColor(resizeImage,grayImage,CV_BGR2GRAY);
equalizeHist(grayImage,equalizeHistImage);
contrastandbrightImage= Mat::zeros( equalizeHistImage.size(), equalizeHistImage.type() );
for(int y = 0; y < equalizeHistImage.rows; y++ )
{
for(int x = 0; x <equalizeHistImage.cols; x++ )
{
contrastandbrightImage.at<uchar>(y,x)= saturate_cast<uchar>(6*(equalizeHistImage.at<uchar>(y,x) ));
}
}
blur(contrastandbrightImage,contrastandbrightImage,Size(3,3));
threshold(contrastandbrightImage,thresholdImage, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY_INV);
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
dilate(thresholdImage, dilateImage, element);
dilate(dilateImage, dilateImage, element);
dilate(dilateImage, dilateImage, element);
dilate(dilateImage, dilateImage, element);
dilate(dilateImage, dilateImage, element);
dilateImage.copyTo(ellipseImage);
vector<vector<Point> > twocontours;
vector<Vec4i>twohierarchy;
findContours(ellipseImage,twocontours,twohierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);
vector<Moments> mu(twocontours.size() );
vector<Point2f> mc( twocontours.size() );
for(int k = 0; k < (int)twocontours.size(); k++)
{
if (int(twocontours.at(k).size()) <=60)
{
drawContours(ellipseImage, twocontours, k, Scalar(0), CV_FILLED);
}
else
{
RotatedRect rRect = fitEllipse(twocontours.at(k));
double majorAxis = rRect.size.height > rRect.size.width ? rRect.size.height : rRect.size.width;
double minorAxis = rRect.size.height > rRect.size.width ? rRect.size.width : rRect.size.height;
float rate = majorAxis/minorAxis;
if (rate<1.3)
{
printf("%f\n",rate);
mu[k] = moments( twocontours[k], false );
mc[k] = Point2d( mu[k].m10/mu[k].m00 , mu[k].m01/mu[k].m00 );
printf("x=%f,y=%f\n",mc[k].x,mc[k].y);
printf("图像的长%d,图像的宽%d\n",resizeImage.cols,resizeImage.rows);
Point center = Point(mc[k].x,mc[k].y);
int r = 10;
circle(resizeImage,center,r,Scalar(255,0,0));
if ((int)mc[k].x<(int)2*(resizeImage.cols/3)&&(int)mc[k].x>(int)(resizeImage.cols/3))
{
if ((int)mc[k].y<(int)2*(resizeImage.rows/3)&&(int)mc[k].y>(int)(resizeImage.rows/3))
{
drawContours(resizeImage, twocontours, k, Scalar(255,0,0), CV_FILLED);
printf("蓝色是二维码区域\n");
}
}
}
else
{
drawContours(resizeImage, twocontours, k, Scalar(0,0,255), CV_FILLED);
}
}
}
imshow("缩小图",resizeImage);
imshow("灰度图",grayImage);
imshow("对比度和亮度增强",contrastandbrightImage);
imshow("二值化结果",thresholdImage);
imshow("膨胀",dilateImage);
imshow("长短轴",ellipseImage);
waitKey(0);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
部分结果图:
![这里写图片描述](https://img-blog.csdn.net/20170208003259933?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhaXBwMDYwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![这里写图片描述](https://img-blog.csdn.net/20170208003323865?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhaXBwMDYwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
无二维码图片的结果图:
![这里写图片描述](https://img-blog.csdn.net/20170208003500608?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhaXBwMDYwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)