OpenCV识别数码管穿线法(基础版)
⽂章⽬录
⼀、感想
1.图像预处理迭代
版本1:考虑获得给数字轮廓识别的图像时,是随便挑选阈值的,所以图像就很糟糕。
版本2:通过直接放⼤图像观察具体的RGB数值分布,就能得到⼀个特定的颜⾊通道和阈值。
2.图像形态学运算迭代
版本1:随便选择⼀种形态学运算,得到的效果并不是很好,要么有⼲扰⽩点,要么就是数字之间粘连,要么数码管之间的缝隙还存在
版本2:先开运算去除⽩点,再闭运算进⾏消除数码管之间的缝隙(为了整体轮廓识别)
3.图像轮廓识别迭代
版本1:
利⽤九个数字轮廓识别是从下层⼀层层往上的特性,识别中间三个
vector<vector<Point>>::iterator lt;
for(lt=g_contours.begin()+3;lt<d()-3;lt++)
版本2:
发现如果a、f、g亮的这样的数码管之间没有连接的⼲扰数字会造成⼀个数字被认为是不同的轮廓。
从⽽九个数字有超过九个轮廓,g_rect就会多出3个。
同时我们的数码管板的特性是上层会出现错误的数字(即有断层的数字),中间是好的0-9(即没有断层),下层是好的数字的镜像(即没有断层)
所以轮廓的多出只会出现在上层
因⽽将轮廓for循环的终⽌条件改变⼀下,保证只循环3次。
int s=0;
vector<vector<Point>>::iterator lt;
for(lt=g_contours.begin()+3;s<3;lt++,s++)
版本3:
我们发现有时候识别的结果不是很好,所以就⽆法满⾜触发条件。
但我们注意到我们的⼩车识别时⼤致静⽌的,所以可以采⽤上次识别的三个数字的位置。
4.图像数字排序迭代
版本1
因为轮廓识别时,虽然是从下层往上层,每层都识别完后才移动,但同层之间的识别没有顺序。
所以我们需要对提取的三个轮廓进⾏排序,排序根据左上⾓的坐标进⾏排序。
版本2
容器⾃定义排序:前期⾃⼰的排序有时会出现指针偏移现象⽽失败,后期采⽤sort()函数,⾃定义排序⽅式,效果好还简单。
5.处理视频迭代
版本1
只是修改了g_srcImage的读取⽅式,从图像转变为视频。
版本2
出现了如果⼀开始没有对准图像就报错的现象。原因是因为没对准,所以轮廓识别的结果为0个,所以g_rect为空,所以需要设置触发条件if(contours.size()>=9)
同理,以防万⼀,给排序也设置⼀下触发条件if(g_rect.size()==3)
版本3
数字不要太过频繁地输出,同样结果的话,那输出的数字就不变
⼆、最终版本
1.滤波
(1)测试代码
(2)结论
选择⾼斯滤波更好,Size值为5.
随便过滤⼀下,值不⽤太⾼,不要也⾏。
GaussianBlur(g_srcImage,g_srcImage,Size(5,5),0.0);
2.颜⾊分离和⼆值化
(1)观察颜⾊
⼀直⿏标滑轮拉的话可以看到颜⾊RGB的分布,可以观察要关注的物体的颜⾊和其余区域的颜⾊。这样就能通过观察得到选择特定的颜⾊通道和阈值。
⽐如:这⾥数码管的绿⾊通道就很好,阈值200就很好区分。
(2)结论
我们的摄像头结果对绿⾊和蓝⾊通道的分离很好,我们选择绿⾊的,阈值为200.
#include<opencv2/opencv.hpp>
#include<algorithm>
#include<iostream>
using namespace std;
using namespace cv;
#define W_BLUR "Blur"
#define W_GREEN "Green"
#define W_GREENTHRESHOLD "GreenThreshold"
Mat g_srcImage;
Mat g_srcImageBlur;
Mat g_dstImageGreen;
Mat g_dstImageGreenThreshold;
int g_Blur=11;
int g_dstImageGreenThresholdValue=200;
void mySplit()
{
vector<Mat> channels;
split(g_srcImageBlur,channels);
//绿⾊通道
g_dstImageGreen=channels.at(1);
namedWindow(W_GREEN,WINDOW_NORMAL);
imshow(W_GREEN,g_dstImageGreen);
}rectangle函数opencv
void myThreshold()
{
pyTo(g_dstImageGreenThreshold);
//阈值
g_dstImageGreenThreshold=g_dstImageGreenThreshold>g_dstImageGreenThresholdValue;
namedWindow(W_GREENTHRESHOLD,WINDOW_NORMAL);
imshow(W_GREENTHRESHOLD,g_dstImageGreenThreshold);
}
int main()
{
g_srcImage=imread("N.jpg");
namedWindow("[src]",WINDOW_NORMAL);
imshow("[src]",g_srcImage);
g_srcImageBlur=g_srcImage.clone();
GaussianBlur(g_srcImage,g_srcImageBlur,Size(g_Blur,g_Blur),0.0);
namedWindow(W_BLUR,WINDOW_NORMAL);
imshow(W_BLUR,g_srcImageBlur);
//split channels
mySplit();
/
/threshold=200
myThreshold();
waitKey();
return0;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。