本文是笔者在参加夏令营时对负责项目的一个总结,这个项目的主要内容就是使用摄像头对着一块装有几段数码管的板子,然后识别出数码管所呈现的数字。其实这个项目整体并不难,opencv库 在这个项目中主要是对图片进行处理,获取紧贴数码管数字的一个矩形区域。之后就需要其他算法来进行处理,本文我使用了比较简单但十分有效的穿线法,也是网上很多类似问题的解决方法。后续我可能会使用其他方法来解决这个问题.
#include
#include
using namespace cv;
using namespace std;
Mat g_srcImage;
g_srcImage = imread( "p1.png", 1 );
imshow("原始图",g_srcImage); //显示原始图
1.原始图有可能尺寸大小不合适,可以使用resize函数进行调整
//获取图片的高和宽,方便按比例进行尺寸调整
int w = g_srcImage.cols;
int h = g_srcImage.rows;
resize(g_srcImage,g_srcImage,Size(500,500*h/w));
2.将图片原通道转换为hsv通道,如果原图不是rgb通道,可以修改cvtColor函数中最后一个参数.
Mat hsv;
cvtColor(g_srcImage,hsv,COLOR_BGR2HSV);
//转换为hsv空间
3.最关键的一步!!
//设置hsv的上下限
int iLowH = 59;
int iHighH =255;
int iLowS = 159;
int iHighS = 255;
int iLowV = 190;
int iHighV = 255;
//分离通道
vector hsvsplit;
split(inputt,hsvsplit);
//筛选
inRange(inputt,Scalar(iLowH,iLowS,iLowV),Scalar(iHighH,iHighS,iHighV),hsv);
4.对图片进行膨胀操作,边缘检测,轮廓获取,再用矩形将轮廓框起来.
Mat threshold_output;
vector> contours;
vector hierarchy;
threshold( hsv, threshold_output, 180, 255, THRESH_BINARY );
Mat Imageg = threshold_output.clone();
//imshow( "边缘图", threshold_output );
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
vector > contours_poly( contours.size() );
vector boundRect( contours.size() );
for( unsigned int i = 0; i < contours.size(); i++ )
{
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int unsigned i = 0; i(), 0, Point() );
rectangle( threshold_output, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
}
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat g_srcImage;
g_srcImage = imread( "num.jpeg", 1 );
//获取图片的高和宽,方便按比例进行尺寸调整
int w = g_srcImage.cols;
int h = g_srcImage.rows;
resize(g_srcImage,g_srcImage,Size(250,250*h/w));
imshow("原始图",g_srcImage); //显示原始图
Mat hsv;
cvtColor(g_srcImage,hsv,COLOR_BGR2HSV);
//转换为hsv空间
//设置hsv的上下限
int iLowH = 59;
int iHighH =255;
int iLowS = 159;
int iHighS = 255;
int iLowV = 190;
int iHighV = 255;
//分离通道
vector hsvsplit;
split(g_srcImage,hsvsplit);
//筛选
inRange(g_srcImage,Scalar(iLowH,iLowS,iLowV),Scalar(iHighH,iHighS,iHighV),hsv);
//imshow("hsv效果图",hsv);
//形态学变换
Mat element=getStructuringElement(MORPH_RECT,Size(5,5));//获取核
dilate(hsv,hsv,element); //膨胀
//imshow("膨胀效果图",hsv);
Mat threshold_output;
vector> contours;
vector hierarchy;
threshold( hsv, threshold_output, 180, 255, THRESH_BINARY );
Mat Imageg = threshold_output.clone();
imshow( "边缘图", threshold_output );
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
vector > contours_poly( contours.size() );
vector boundRect( contours.size() );
for( unsigned int i = 0; i < contours.size(); i++ )
{
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int unsigned i = 0; i(), 0, Point() );
rectangle( threshold_output, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
}
imshow("效果图",threshold_output);
waitKey(0);
}
#include
#include
using namespace cv;
using namespace std;
bool cross(Mat image,int x1,int y1,int x2,int y2);
int getnum(Mat image);
int getgrey(Mat image,int x,int y);
int main()
{
Mat g_srcImage;
g_srcImage = imread( "num.jpeg", 1 );
//获取图片的高和宽,方便按比例进行尺寸调整
int w = g_srcImage.cols;
int h = g_srcImage.rows;
resize(g_srcImage,g_srcImage,Size(250,250*h/w));
imshow("原始图",g_srcImage); //显示原始图
Mat hsv;
cvtColor(g_srcImage,hsv,COLOR_BGR2HSV);
//转换为hsv空间
//设置hsv的上下限
int iLowH = 59;
int iHighH =255;
int iLowS = 159;
int iHighS = 255;
int iLowV = 190;
int iHighV = 255;
//分离通道
vector hsvsplit;
split(g_srcImage,hsvsplit);
//筛选
inRange(g_srcImage,Scalar(iLowH,iLowS,iLowV),Scalar(iHighH,iHighS,iHighV),hsv);
//imshow("hsv效果图",hsv);
//形态学变换
Mat element=getStructuringElement(MORPH_RECT,Size(5,5));//获取核
dilate(hsv,hsv,element); //膨胀
//imshow("膨胀效果图",hsv);
Mat threshold_output;
vector> contours;
vector hierarchy;
threshold( hsv, threshold_output, 180, 255, THRESH_BINARY );
Mat Imageg = threshold_output.clone();
imshow( "边缘图", threshold_output );
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
vector > contours_poly( contours.size() );
vector boundRect( contours.size() );
for( unsigned int i = 0; i < contours.size(); i++ )
{
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( int unsigned i = 0; i(), 0, Point() );
rectangle( threshold_output, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
}
imshow("效果图",threshold_output);
Rect roirect;
for (int unsigned i = 0;i3.5&& (double(boundRect[i].height)/double(boundRect[i].width))<5)
{
roirect = boundRect[i];
Mat final;
final = Imageg(roirect);
int num;
num = 1;
}
else if ((double(boundRect[i].height)/double(boundRect[i].width))>1.35&& (double(boundRect[i].height)/double(boundRect[i].width))<2.4)
{
roirect = boundRect[i];
Mat final;
final = Imageg(roirect);
int num;
num = getnum(final);
if (num != -1)
{
cout <<"get the num: "<200)return true;
}
return false;
}
else
{
for (int x = x1;x200)return true;
}
return false;
}
}
int getnum(Mat image)
{
int h = image.rows;
int w = image.cols;
int result;
bool a1,a2,a3,a4,a5,a6,a7;
if(cross(image,int(0.5*w),0,int(0.5*w),int(0.25*h)))a1 = true;
else a1=false;
if(cross(image,0,int(0.25*h),int(0.5*w),int(0.25*h)))a2 = true;
else a2=false;
if(cross(image,int(0.5*w),int(0.25*h),int(w),int(0.25*h)))a3 = true;
else a3=false;
if(cross(image,int(0.5*w),int(0.25*h),int(0.5*w),int(0.75*h)))a4 = true;
else a4=false;
if(cross(image,0,int(0.75*h),int(0.5*w),int(0.75*h)))a5 = true;
else a5=false;
if(cross(image,int(0.5*w),int(0.75*h),int(w),int(0.75*h)))a6 = true;
else a6=false;
if(cross(image,int(0.5*w),int(0.75*h),int(0.5*w),int(h)))a7 = true;
else a7=false;
if(a1 !=0&&a2 ==0&&a3 !=0&&a4 !=0&&a5 !=0&&a6 ==0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 2;
else if(a1 !=0&&a2 ==0&&a3 !=0&&a4 !=0&&a5 ==0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 3;
else if(a1 ==0&&a2 !=0&&a3 !=0&&a4 !=0&&a5 ==0&&a6 !=0&&a7 ==0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 4;
else if(a1 !=0&&a2 !=0&&a3 ==0&&a4 !=0&&a5 ==0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 5;
else if(a1 !=0&&a2 !=0&&a3 ==0&&a4 !=0&&a5 !=0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 6;
else if(a1 !=0&&a2 ==0&&a3 !=0&&a4 ==0&&a5 ==0&&a6 !=0&&a7 ==0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 7;
else if(a1 !=0&&a2 ==0&&a3 !=0&&a4 ==0&&a5 ==0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 7;
else if(a1 !=0&&a2 !=0&&a3 !=0&&a4 !=0&&a5 !=0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 8;
else if(a1 !=0&&a2 !=0&&a3 !=0&&a4 !=0&&a5 ==0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 9;
else if(a1 !=0&&a2 !=0&&a3 !=0&&a4 ==0&&a5 !=0&&a6 !=0&&a7 !=0&&(getgrey(image,w*0.5,h*0.25) <= 150)&&(getgrey(image,w*0.5,h*0.75) <= 150)) result = 0;
else
{
result = -1;
}
//cout <<"result"<::iterator it = image.begin();
Mat_::iterator itend = image.end();
int pixel = *(it + y * w + x);
return pixel;
}
get the num: 8
get the num: 8
get the num: 5
get the num: 8
get the num: 6
get the num: 8
get the num: 9
get the num: 0