当前位置: 首页 > news >正文

网站内容多 询盘网页设计网站哪个公司好

网站内容多 询盘,网页设计网站哪个公司好,深圳机械网站建设,全包装修** 关于胶囊检测的思考-代码实现 作者#xff1a;Simon Song** 先看两张图。我们要实现对生产胶囊的快速检测#xff0c;有两种方案#xff0c;一种是DNN方式#xff0c;一种是openCV方法。为避开大量样本集的问题#xff0c;我选择的是openCV方式实现胶囊检测。 检测…** 关于胶囊检测的思考-代码实现 作者Simon Song** 先看两张图。我们要实现对生产胶囊的快速检测有两种方案一种是DNN方式一种是openCV方法。为避开大量样本集的问题我选择的是openCV方式实现胶囊检测。 检测规则如下 一、三个胶囊不全为空且检测结果均为好品该幅图判断为好品。三个胶囊不全为空有至少一个胶囊为坏品该幅图判断为坏品。 二、每个胶囊分别检测顶部蓝色数字代表每个胶囊检测结果 -1空 0好品 其他大于1的数字代表不同缺陷种类请自行编号。 三、左侧显示检测参数例如W宽H高DA脏点面积。可按实际需要显示。 四、好品胶囊标注为绿色。坏品胶囊标注为红色相应错误参数也标注为红色。 代码环境 VS2005openCV341C 先给出我的实现代码 #includeiostream #includeopencv2/opencv.hppusing namespace std; using namespace cv; //定义所需文件路径 string sample_path G:/opencv_trainning/vs2015/myself_project/Capsule_Picture/;//样本路径 string good_example G:/opencv_trainning/vs2015/myself_project/Capsule_Picture/good_example/goodmodel.bmp;//好的模板 //定义数据结构,用于返回数据方便操作 typedef struct mydata{char classification;//分类,-1:坏品,0好品,1:异形2:大小端,3气泡4黑点, 5:空位置short width;//宽short height;//高double area;//面积//其他再添加 } Mydata;//起个别名方便调用 vectorstring filelist;//文件列表 //定义变量和判断函数 vectorvectorPoint model_contours;//模型轮廓 vectorVec4i model_hierarchy;//模型拓扑结构 int max_model_contours;//模型最大轮廓变量 void model_reader(void);//模型读取器 Mat processing(Mat capsule,Mat black_mask,Mat small_mask);//胶囊图片处理 bool is_empty_func(Mat mask);//判空函数 bool is_alien_func(Mat mask,Mydata data);//判变异函数 bool is_big_and_small_func(Mat mask, Mydata data);//判断大小头函数 bool is_bobble_and_blackP_func(Mat capsule,Mat mask, Mydata data);//判气泡和黑点函数绘制问题位置 Mydata capsule_processing_funciton(Mat capsule,Mat mask,Matsmall_mask);//胶囊处理函数,返回胶囊所需数据 void drawCapsule_function(Mat capsule,Matblk_mask,Mat mask,Mat small_mask,Mydata data);//绘制胶囊掩码 void putText_function(Mat src,Rectpos,Mydata data);//在图片上写文本void drawDashContours(InputOutputArray image, InputArrayOfArrays contours,int contourIdx, const Scalar color, int thinkness, int lineType,int gap_threshold);//自定义函数实现画虚线轮廓/*此文件用于胶囊检测验证目录中已提供了样本图说明 */ int main(int argc, char** argv) {//读取文件列表ifstream file((sample_pathfile.txt).c_str());//定义文件流if (!file.is_open()) {//打开文件cout open fault endl;return -1;}string line;//定义字符串while (!file.eof()) {//当文件可读时//读取一行参数文件流字符串getline(file, line);//printf(%s\n,line.c_str());//打印提示//写入文件列表转为c字符串保存filelist.push_back(line.c_str());}//读取好的模型model_reader();//循环处理图片int index 0;//索引位置Mat src;//定义图矩阵while (index filelist.size()){//当位置有效时cout file_path: filelist[index] endl;;//显示文件名//读取图片参数文件名位置后加1src imread(filelist[index]);if (src.empty()) {//判空处理cout open fault endl;return -1;}//显示imshow(src, src);//发现黑色框Mat black_mask;inRange(src, Scalar(0, 0, 0), Scalar(180, 255, 46), black_mask);//获取黑色区域bitwise_not(black_mask, black_mask);//反色处理得到胶囊的黑框部分//图形学-闭操作使得边缘更好//参数形状核尺寸锚点Mat kernel getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));//定义结构元素//参数图目标图操作标记结构元素锚点迭代次数 其他参数默认morphologyEx(black_mask, black_mask, MORPH_CLOSE, kernel, Point(-1, -1), 8);//闭操作处理//腐蚀-让边缘收进去一部分//参数图目标图操作标记结构元素锚点迭代次数 其他参数默认morphologyEx(black_mask, black_mask, MORPH_ERODE, kernel, Point(-1, -1),5);//腐蚀操作处理,8//获得掩码图用于显示Mat black_mask_img;src.copyTo(black_mask_img,black_mask);//获得胶囊以外的图//imshow(black_mask_img,black_mask_img);//显示bitwise_not(black_mask,black_mask);//反色操作得到胶囊位置为黑色//imshow(black_mask, black_mask);//显示//0.0转为灰度图Mat gray;//定义灰度图cvtColor(src,gray,CV_BGR2GRAY);//imshow(gray,gray);//GaussianBlur(gray,gray);//0.1二值化图Mat binary;//二值化图//参数灰度图目标图低阈值最大值阈值模式threshold(gray,binary,0,255,CV_THRESH_BINARY|CV_THRESH_OTSU);//多峰自动阈值//imshow(binary, binary);//0.2图形学-闭操作去除内部干扰//参数形状宏定义核尺寸锚点Mat element getStructuringElement(MORPH_RECT,Size(10,10),Point(-1,-1));//定义结构元素//参数图目标图操作宏定义结构元素其他参数默认morphologyEx(binary,binary,MORPH_CLOSE,element,Point(-1,-1));//闭操作//1.获得每个一个胶囊的位置图片//1.1发现轮廓只找最外层的轮廓vectorvectorPoint contours;//轮廓向量vectorVec4i hierarchy;//拓扑结构变量单个结构数据含义为[后一个标记位置前一个标记位置子轮廓标记位置父轮廓标记位置]//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(binary,contours,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(0,0));//1.2获取每个胶囊图Mat contoursImgsrc.clone();//克隆图为了整体显示vectorMat capsules;//胶囊向量vectorMat blk_mask;//胶囊掩码向量vectorMat small_mask;//胶囊的小掩码vectorRect good_pos;//好的胶囊位置for (int c 0; c contours.size(); c) {//循环轮廓位置//计算面积,参数单个轮廓double area contourArea(contours[c]);if (area/100 600)continue;//当面积太小继续下一次cout area/100 area / 100 endl;//打印提示//获得框位置参数单个轮廓返回矩形变量Rect pos boundingRect(contours[c]);//截取图片局部capsules.push_back(src(pos));//截取掩码局部blk_mask.push_back(black_mask(pos));//保存好的矩形位置信息,后面使用good_pos.push_back(pos);//保存全黑图到小胶囊掩码,后面使用small_mask.push_back(Mat::zeros(pos.height,pos.width,CV_8UC1));//绘制到图上参数图rect变量颜色线宽rectangle(contoursImg,pos,Scalar(0,0,255),1);//显示每个胶囊//imshow(format(capsules[%d], capsules.size() - 1).c_str(),capsules[capsules.size()-1]);}cout -------- endl;//中断打印提示//imshow(contoursImg,contoursImg);//Mat processing_board src.clone();//克隆一张图给处理图后面用于显示vectorchar class_group;//分类组变量用于统计各种综合情况的变量//2.检测胶囊内的几种情况空异型气泡黑点等for (int c 0; c capsules.size(); c) {//循环胶囊//显示胶囊//imshow(org_capsule,capsules[c]);//处理图片为纯胶囊掩码图方便后面操作参数胶囊原图胶囊位置掩码胶囊小掩码图Mat mask processing(capsules[c],blk_mask[c], small_mask[c]);//胶囊处理获得胶囊数据参数胶囊原图胶囊小掩码图Mydata data capsule_processing_funciton(capsules[c],mask,small_mask[c]);//绘制胶囊线参数胶囊原图胶囊位置掩码纯胶囊掩码胶囊小掩码胶囊数据drawCapsule_function(capsules[c],blk_mask[c],mask,small_mask[c],data);//绘制文本参数图胶囊位置信息(rect)胶囊数据putText_function(src, good_pos[c],data);//保存分类号class_group.push_back(data.classification);}//判断整体好品情况if ((class_group[0]5class_group[1]5class_group[3]5)当全为空5时||(class_group[0] ! 0|| class_group[1] ! 0|| class_group[2] ! 0)) {//或当有不为好0时为坏品//放入文字-坏品//参数图文本原点字体缩放比颜色线宽线型底左对齐(倒过来的效果)putText(src,Bad,Point(0,25),CV_FONT_NORMAL,1.0,Scalar(0,0,255),1,8,false);}else {//否则为好品//放入文字-好品//参数图文本原点字体缩放比颜色线宽线型底左对齐(倒过来的效果)putText(src, Good, Point(0, 20), CV_FONT_NORMAL, 1.0, Scalar(0, 255, 0), 1, 8, false);}imshow(processing_board, src);cv::waitKey(4000);//显示等待}cv::waitKey(0);//按键等待return 0; }void model_reader(void) {//模型读取器//读取模板图Mat good_model imread(good_example.c_str(), IMREAD_GRAYSCALE);//灰度图if (good_model.empty()) { //判空处理cout read model fault endl;return;}//imshow(model_gray,good_model);//显示//二值化图Mat model_bianry;//定义二值化图//参数灰度图二值化画图阈值最大值二值化标记threshold(good_model, model_bianry, 230, 255, CV_THRESH_BINARY | CV_THRESH_TRIANGLE);//单峰自动//imshow(model_bianry, model_bianry);//图形学-闭操作去掉外围噪点//定义元素结构参数形状核尺寸锚点Mat element getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));//开操作参数图目标图操作标记结构元素锚点迭代次数其他参数默认morphologyEx(model_bianry,model_bianry,MORPH_CLOSE,element,Point(-1,-1),1);//反色,获得黑底白面图 参数原图目标图bitwise_not(model_bianry,model_bianry);//imshow(model_morphologyEx, model_bianry);//显示//模型轮廓发现,参数二值化画图模型轮廓模型拓扑结构检测方法发现方法偏移量findContours(model_bianry, model_contours, model_hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));//发现最大的那个轮廓double max_area 0;//最大面积变量int max_pos -1;//最大位置变量for (int c 0; c model_contours.size(); c) {//循环模型轮廓位置double area contourArea(model_contours[c]);//计算面积if (area max_area) {//当前轮廓面积大于最大面积时max_area area;//赋值最大值max_pos c;//保存最大位置}}max_model_contours max_pos;//赋值到全局变量cout max_model_contours max_model_contours endl;//打印测试//显示模型轮廓图Mat model_contours_img Mat::zeros(good_model.size(),good_model.type());//定义显示图//参数图轮廓向量轮廓位置下标颜色线宽线型拓扑结构变量drawContours(model_contours_img,model_contours, max_model_contours,Scalar(255),-1,8,model_hierarchy);//绘制最大轮廓//imshow(model_contours_img, model_contours_img);//显示//清除向量重新发现轮廓确保掩码的一致性model_contours.clear();//轮廓清除model_hierarchy.clear();//拓扑结构变量清除max_area 0;//最大面积变量max_pos -1;//最大位置变量//模型再次轮廓发现,参数二值化画图模型轮廓模型拓扑结构检测方法发现方法偏移量findContours(model_contours_img, model_contours, model_hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));//发现最大的那个轮廓for (int c 0; c model_contours.size(); c) {//循环轮廓位置double area contourArea(model_contours[c]);//计算面积if (area max_area) {//当前轮廓面积大于最大面积时max_area area;//赋值最大值max_pos c;//保存最大位置}} }//定义判断函数:颜色掩码二值化掩码实际掩码 Mat processing(Mat capsule, Mat black_mask,Mat small_mask) {//胶囊图片处理//显示原图//imshow(capsule,capsule);//获得反的掩码图(黑底白面)Mat ref_black_mask;//定义反色掩码图bitwise_not(black_mask,ref_black_mask);//反色处理//imshow(ref_black_mask, ref_black_mask);//按颜色范围获得黄颜色掩码//转为hsvMat hsv;//定义HSV图cvtColor(capsule,hsv,CV_BGR2HSV);//参数图1图2转换标记//提取黄色Mat mask_yellow;//定义掩码图inRange(hsv,Scalar(26,43,46),Scalar(34,255,255),mask_yellow);//获取掩码参数图低值高值掩码图//掩码处理Mat new_mask_yellow;//定义新图mask_yellow.copyTo(new_mask_yellow,ref_black_mask);//掩码拷贝胶囊使其在胶囊范围内//图形学-开操作去掉外面的噪点Mat element_yellow getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));//参数形状核尺寸锚点morphologyEx(new_mask_yellow, new_mask_yellow, MORPH_OPEN, element_yellow, Point(-1, -1), 4);//参数原图目标图操作标记元素矩阵锚点迭代次数其他参数默认//imshow(inRange, new_mask_yellow);//使用二值化获得黑白图//灰度图Mat gray;//定义灰度图cvtColor(capsule,gray,CV_BGR2GRAY);//参数原图目标图转换标记//二值化处理Mat binary;//定义二值化图threshold(gray,binary,230,255,THRESH_BINARY);//参数图二值化图阈值最大值阈值标记//反色处理bitwise_not(binary,binary);//获得掩码图Mat new_binary;binary.copyTo(new_binary,ref_black_mask);//获得胶囊的框内掩码图参数新图掩码//图像学-开操作Mat element getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));//定义核元素参数形状核尺寸锚点morphologyEx(new_binary,new_binary,MORPH_OPEN,element,Point(-1,-1),4);//开操作参数图目标图操作标记核元素锚点迭代次数其他参数默认//imshow(threshold_mask, new_binary);//合并掩码图Mat mask;//定义总掩码图bitwise_or(new_mask_yellow,new_binary,mask);//或处理得到完成掩码参数图1图2掩码图//图形学-闭操作Mat element_mask getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));//定义核元素参数形状核尺寸锚点morphologyEx(mask, mask, MORPH_CLOSE, element_mask, Point(-1, -1), 2);//闭操作参数图目标图操作标记核元素锚点迭代次数其他参数默认//imshow(mask,mask);//单掩码处理//1.发现轮廓vectorvectorPoint capsule_contours;//轮廓向量vectorVec4i capsule_hierarchy;//拓扑结构变量//参数二值化图轮廓向量拓扑结构变量检测方法发现方法偏移量findContours(mask, capsule_contours, capsule_hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));//当没有轮廓时返回全黑图if (capsule_contours.size()1) {return Mat::zeros(mask.size(), mask.type());}//发现最大的那个轮廓double max_area 0;//最大面积变量int max_pos -1;//最大位置变量for (int c 0; c capsule_contours.size(); c) {double area contourArea(capsule_contours[c]);//计算面积if (area max_area) {//当前轮廓面积大于最大面积时max_area area;//赋值最大面积max_pos c;//保存最大位置}}//当面积太小时返回全黑double area contourArea(capsule_contours[max_pos])/100;//计算面积,/100方便计算参数:(单个轮廓)cout area area endl;if (area10) {return Mat::zeros(mask.size(),mask.type());}//绘制轮廓Mat contours_mask Mat::zeros(mask.size(), mask.type());//定义图drawContours(contours_mask, capsule_contours, max_pos, Scalar(255), -1, 8, capsule_hierarchy);//绘制轮廓//imshow(contours_mask, contours_mask);//显示//获取原图内容Mat capsule_small_mask;//定义胶囊小图gray.copyTo(capsule_small_mask,contours_mask);//获得灰度图的胶囊部分参数新图掩码//imshow(capsule_small_mask, capsule_small_mask);//二值化处理Mat binary_small_mask;//定义二值化图threshold(capsule_small_mask, binary_small_mask,200,255,THRESH_BINARY);//参数图二值化图阈值最大值二值化操作标记//图像学-闭操作去内噪点此处不需要故注掉//Mat element_test getStructuringElement(MORPH_RECT,Size(3,3),Point(0,0));//定义核元素参数形状核尺寸锚点//morphologyEx(binary_small_mask,binary_small_mask,MORPH_CLOSE,element,Point(-1,-1),1);//闭操作参数图目标图操作标记核元素锚点迭代次数其他参数默认//发现轮廓vectorvectorPoint small_mask_contours;//轮廓向量vectorVec4i small_mask_hierarchy;//拓扑结果向量//参数二值化图轮廓向量拓扑结构变量检测方法发现方法偏移量findContours(binary_small_mask,small_mask_contours,small_mask_hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));//循环查找面积最大的那个double small_mask_max_area-1;//定义小轮廓最大面积int small_mask_max_area_pos-1;//定义最大面积的位置for (int i 0; i small_mask_contours.size();i) {//循环轮廓位置double area contourArea(small_mask_contours[i]);//计算面积if (area small_mask_max_area) {//当前面积大于最大面积时,small_mask_max_area_pos i;//记录位置small_mask_max_area area;//更改最大面积}}//发现凸包vectorvectorPoint convex_contours(small_mask_contours.size());//定义凸包个数为一致大小for (int i 0; i small_mask_contours.size(); i) {//循环轮廓位置//发现凸包, 参数原轮廓向量目标轮廓向量顺时针方向状态返回点状态convexHull(small_mask_contours[i], convex_contours[i], false, true);//获得凸包//逼近多边形,参数原轮廓向量目标轮廓向量,最小量闭包状态,放在此处不合适//approxPolyDP(small_mask_contours[i],convex_contours[i],5,true);}//绘制小轮廓drawContours(small_mask, convex_contours, small_mask_max_area_pos,Scalar(255),-1);//绘制轮廓//imshow(small_mask, small_mask);return contours_mask;//返回 }bool is_empty_func(Mat mask) {//判空函数//1.发现轮廓vectorvectorPoint capsule_contours;//轮廓向量vectorVec4i capsule_hierarchy;//拓扑结构变量//参数二值化图轮廓向量拓扑结构变量检测方法发现方法偏移量findContours(mask,capsule_contours,capsule_hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(-1,-1));if (capsule_contours.size()1) {//当没有轮廓时return true;//返回真表示没有胶囊}//计算总面积double area 0;//白区面积for (int c 0; c capsule_contours.size(); c) {//循环胶囊轮廓//cout hierarchy capsule_hierarchy[c][0] , capsule_hierarchy[c][1] , capsule_hierarchy[c][2] , capsule_hierarchy[c][3] endl;area contourArea(capsule_contours[c]) / 100;//计算面积并累加,/100是为了方便计算}cout area/100 area endl;//打印提示//判断返回if (area300) {//空处理,按照白面积计算判断return true;//返回真}else{//否则return false;//返回假} }bool is_alien_func(Mat mask, Mydata data) {//判变异函数//1.发现轮廓vectorvectorPoint capsule_contours;//轮廓向量vectorVec4i capsule_hierarchy;//拓扑结构变量//参数二值化图轮廓向量拓扑结构变量检测方法发现方法偏移量findContours(mask,capsule_contours,capsule_hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(-1,-1));//发现最大的那个轮廓double max_area 0;//最大面积变量int max_pos -1;//最大位置变量RotatedRect max_rrect;//定义最大斜矩阵for (int c 0; c capsule_contours.size(); c) {double area contourArea(capsule_contours[c]);//计算面积if (area max_area) {//当前轮廓面积大于最大面积时max_area area;//赋值最大面积max_pos c;//保存最大位置max_rrect minAreaRect(capsule_contours[c]);//获得斜矩阵}}//给定数据,为何防止出现宽高显示不对的情况人为调整一下Mydata local_data;//定义本地结构变量local_data.height (max_rrect.size.heightmax_rrect.size.width? max_rrect.size.height: max_rrect.size.width);//给定高local_data.width (max_rrect.size.heightmax_rrect.size.width ? max_rrect.size.width : max_rrect.size.height);//给定宽local_data.area max_area;//给定面积//绘制轮廓为了显示Mat contours_img Mat::zeros(mask.size(), mask.type());//定义图drawContours(contours_img,capsule_contours,max_pos,Scalar(255),-1,8,capsule_hierarchy);//绘制轮廓//imshow(is_alien_func_contours, contours_img);//显示/*//从点数量上无法判别异形的特点故注掉//2.使用最小多边形点位置判断是否为异型//2.1胶囊的最小轮廓点vectorvectorPoint min_contours(1);//轮廓数量与轮廓向量一致,此处1个就行//基于RDP获得最小轮廓点 多变型轮廓点数量,参数原轮廓目标轮廓最小量封闭状态approxPolyDP(capsule_contours[max_pos],min_contours[0],5,true);printf(capsule min_contours[%d].size()%d\n,0, min_contours[0].size());//2.2模型的最小轮廓vectorvectorPoint model_min_contours(1);//轮廓数量与轮廓向量一致,此处1个就行//基于RDP获得最小轮廓点 多变型轮廓点数量,参数原轮廓目标轮廓最小量封闭状态approxPolyDP(model_contours[max_model_contours],model_min_contours[0],5,true);printf(model min_contours[%d].size()%d\n, 0, model_min_contours[0].size());//绘制,Mat compare_contours_img Mat::zeros(mask.size(),CV_8UC3);drawContours(compare_contours_img, min_contours,0,Scalar(0,0,255),1);drawContours(compare_contours_img, model_min_contours, 0, Scalar(0, 255, 0), 1);imshow(compare_contours_img, compare_contours_img);//2.3形状比较,完全相同返回0最大值为1参数轮廓1轮廓2轮廓匹配表示CV_CONTOURS_MATCH_I1/I2/I3,0double score matchShapes(model_min_contours[0], min_contours[0], CV_CONTOURS_MATCH_I1, 0);cout score score endl;//打印提示//判断得分if (score 0.10) {//大于10%返回trueputText(compare_contours_img, alien, Point(20, 20), CV_FONT_NORMAL, 0.5, Scalar(0, 0, 255), 1);//添加文字显示imshow(compare_contours_img, compare_contours_img);return true;//返回真}else {//否则返回假putText(compare_contours_img, normal, Point(20, 20), CV_FONT_NORMAL, 0.5, Scalar(0, 255, 0), 1);//添加文字显示imshow(compare_contours_img, compare_contours_img);return false;//返回假}*///2.使用凸包测试//2.1胶囊的最大轮廓点vectorvectorPoint convex_contours(1);//轮廓数量与轮廓向量一致,此处1个就行//获得凸包,参数原轮廓目标轮廓顺时针方向状态返回点状态convexHull(capsule_contours[max_pos], convex_contours[0],false,true);//printf(capsule min_contours[%d].size()%d\n, 0, convex_contours[0].size());//2.2模型的最大轮廓vectorvectorPoint model_convex_contours(1);//轮廓数量与轮廓向量一致,此处1个就行//获得凸包,参数原轮廓目标轮廓顺时针方向状态返回点状态convexHull(model_contours[max_model_contours], model_convex_contours[0],false,true);//printf(model min_contours[%d].size()%d\n, 0, model_convex_contours[0].size());//绘制轮廓方便观察Mat compare_contours_img Mat::zeros(mask.size(), CV_8UC3);//定义比较图//参数图轮廓轮廓下标位置颜色线宽drawContours(compare_contours_img, convex_contours, 0, Scalar(0, 0, 255), 1);drawContours(compare_contours_img, model_convex_contours, 0, Scalar(0, 255, 0), 1);//imshow(compare_contours_img, compare_contours_img);//2.3形状比较,完全相同返回0最大值为1参数轮廓1轮廓2轮廓匹配表示CV_CONTOURS_MATCH_I1/I2/I3,0double score matchShapes(model_convex_contours[0], convex_contours[0], CV_CONTOURS_MATCH_I1, 0);cout score score endl;//打印提示//判断得分if (score 0.10) {//大于10%返回true//putText(compare_contours_img,alien,Point(20,20),CV_FONT_NORMAL,0.5,Scalar(0,0,255),1);//添加文字显示//imshow(compare_contours_img, compare_contours_img);//给定值data.classification 1;//给定异形类别data.height local_data.height;//高data.width local_data.width;//宽data.area local_data.area;//面积return true;//返回真}else {//否则返回假//putText(compare_contours_img, normal, Point(20, 20), CV_FONT_NORMAL, 0.5, Scalar(0, 255, 0), 1);//添加文字显示//imshow(compare_contours_img, compare_contours_img);return false;//返回假} }bool is_big_and_small_func(Mat mask,Mydata data) {//判断大小头函数//imshow(is_big_and_small_func,mask);//发现轮廓vectorvectorPoint contours;//轮廓向量vectorVec4i hierarchy;//拓扑结构向量//参数二值化图轮廓向量拓扑结构向量发现方法检测方法偏移量点findContours(mask,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point(0,0));//获得斜矩阵RotatedRect rotaterect minAreaRect(contours[0]);//给定本地数据,宽高认为调整一下以便显示正常Mydata Local_data;//定义本地数据Local_data.height (rotaterect.size.heightrotaterect.size.width? rotaterect.size.height: rotaterect.size.width);//赋值高Local_data.width (rotaterect.size.heightrotaterect.size.width ? rotaterect.size.width : rotaterect.size.height);//赋值宽Local_data.area contourArea(contours[0]);//赋值面积//更改斜矩阵大小获得25%和75%的直线int height rotaterect.size.height;//获得高int width rotaterect.size.width;//获得宽//cout width width endl;//cout height height endl;RotatedRect rrect_25_75 rotaterect;//25%,75%RotatedRect rrect rotaterect;//50%Point2f rrect25_75_points[4];//定义点信息Point2f rrect_points[4];//定义点信息if (widthheight) {//宽大,调宽//调整25%和75%rrect_25_75.size.width width / 2;//高处理rrect_25_75.points(rrect25_75_points);//获得四个点信息//50%处理rrect.size.width 1;//高处理rrect.points(rrect_points);//获得四个点信息}else {//否则高大调高//调整25%和75%rrect_25_75.size.height height / 2;//高处理rrect_25_75.points(rrect25_75_points);//获得四个点信息//50%处理rrect.size.height 1;//高处理rrect.points(rrect_points);//获得四个点信息}//在新的掩码图中绘制直线Mat new_maskmask.clone();//定义图片;for (int i 0; i 4;i) {//循环点位置//绘制线,25_75//line(new_mask, rrect25_75_points[i], rrect25_75_points[(i1)%4],Scalar(0),1,LINE_AA);//绘制线50line(new_mask,rrect_points[i], rrect_points[(i1)%4],Scalar(0),5,LINE_AA);}//imshow(new_mask, new_mask);/*//换个思路先注掉此思路只对明显大小头有效//反色获得直线图,并掩码只剩下白色直线Mat ref_new_mask;bitwise_not(new_mask,ref_new_mask);//非操作得到反色图Mat and_ref_new_mask;bitwise_and(ref_new_mask,mask,and_ref_new_mask);//与掩码图像得到纯值线图//图形学-开操作取出外侧的零散边缘Mat element getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));morphologyEx(and_ref_new_mask, and_ref_new_mask,MORPH_OPEN,element,Point(-1,-1),1);imshow(ref_new_mask, and_ref_new_mask);//霍夫直线获得直线坐标vectorVec4f lines;//定义直线向量//参数8位灰度图vec4f的向量像素扫描步长角度扫描步长交点阈值最小直线长度最大长度间隔HoughLinesP(and_ref_new_mask,lines,1,CV_PI/180,30,mask.cols/2,10);//搜索合适的直线Point2f pointlines[3][2] {0,0,0,0,0,0};//用于保存最长直线位置方便后续操作float lengths[3] {0,0,0};//用于保存长度的数组[0]为上线[1]位置为中线[2]位置为下线cout lines.size() lines.size() endl;Mat hough_img Mat::zeros(mask.size(),CV_8UC3);for (int c 0; c lines.size();c) {//循环线Vec4f hline lines[c];//获得点前向量float length abs(hline[0] - hline[2]) abs(hline[1] - hline[3]);//计算长度//判断,hline[1]表示y位置if (hline[1]100 hline[1]200lengthlengths[0]) {//上线,且大于最大长度//保存点向量pointlines[0][0]Point(hline[0], hline[1]);//点1pointlines[0][1] Point(hline[2], hline[3]);//点2//保存长度lengths[0] length;}else if (hline[1]200 hline[1]300lengthlengths[1]) {//中线且大于最大长度//保存点向量pointlines[1][0] Point(hline[0], hline[1]);//点1pointlines[1][1] Point(hline[2], hline[3]);//点2//保存长度lengths[1] length;}else if (hline[1]300lengthlengths[2]) {//下线且大于最大长度//保存点向量pointlines[2][0] Point(hline[0], hline[1]);//点1pointlines[2][1] Point(hline[2], hline[3]);//点2//保存长度lengths[2] length;}}//绘制显示//画线line(hough_img, pointlines[0][0], pointlines[0][1], Scalar(0, 0, 255), 1);//上线line(hough_img, pointlines[1][0], pointlines[1][1], Scalar(0, 0, 255), 1);//中线line(hough_img, pointlines[2][0], pointlines[2][1], Scalar(0, 0, 255), 1);//下线printf(Point(%f,%f),Point(%f,%f),length%f\n, pointlines[0][0].x, pointlines[0][0].y, pointlines[0][1].x, pointlines[0][1].y, lengths[0]);//打印提示,上线printf(Point(%f,%f),Point(%f,%f),length%f\n, pointlines[1][0].x, pointlines[1][0].y, pointlines[1][1].x, pointlines[1][1].y, lengths[1]);//打印提示,上线printf(Point(%f,%f),Point(%f,%f),length%f\n, pointlines[2][0].x, pointlines[2][0].y, pointlines[2][1].x, pointlines[2][1].y, lengths[2]);//打印提示,上线imshow(hough_img, hough_img);//筛选并计算直线长度c^2|x1-x2|^2|y1-y2|^2//比较长度当大于N个点时应给大小头否则为正常范围内的胶囊// ----- 1// ----- 2// ----- 3// 大小端的全部条件// 线1与线3的差值绝对值较大// 线1与线2的差值绝对值较大// 线2与线3的差值绝对值较大*///发现轮廓,后面比较上下两部分vectorvectorPoint half_contours;//轮廓向量vectorVec4i half_hierarchy;//拓扑结构//参数二值化图轮廓向量拓扑结构向量发现方法检测方法偏移量点findContours(new_mask,half_contours,half_hierarchy,RETR_LIST,CHAIN_APPROX_NONE,Point(0,0));cout half_contours.size() half_contours.size() endl;//形状比较, 完全相同返回0最大值为1参数轮廓1轮廓2轮廓匹配表示CV_CONTOURS_MATCH_I1 / I2 / I3, 0double score matchShapes(half_contours[0],half_contours[1],CV_CONTOURS_MATCH_I3,0);cout is_big_and_small_func:scorescore endl;//判断if (score 0.085) {//当得分大于0.085时返回真表示大小头,此值需要按实际调整//给定数据data.classification 2;//赋值分类器2为大小端data.height Local_data.height;//赋值高data.width Local_data.width;//赋值宽data.area Local_data.area;//赋值面积return true;}else {//否则return false;//返回假} }bool is_bobble_and_blackP_func(Mat capsule,Mat mask,Mydata data) {//判气泡和黑点函数绘制问题位置//获得轮廓原图Mat capsule_org;//定义胶囊图capsule.copyTo(capsule_org, mask);//掩码拷贝图//imshow(is_bobble_and_blackP_func:capsule_org, capsule_org);//灰度图Mat gray;cvtColor(capsule_org,gray,CV_BGR2GRAY);//二值化Mat binary;//二值化图//threshold(gray,binary,130,255,THRESH_BINARY_INV);//二值化Canny(capsule,binary,150,230,3,true);//canny//imshow(is_bobble_and_blackP_func:binary,binary);//掩码图片Mat new_binary;binary.copyTo(new_binary,mask);//膨胀处理使位置更明显Mat element getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));//定义结构元素参数形状核尺寸锚点morphologyEx(new_binary,new_binary,MORPH_DILATE,element,Point(-1,-1),1);//膨胀处理参数图目标图操作标记核元素锚点迭代次数//imshow(binary_mask,new_binary);//1.发现轮廓vectorvectorPoint capsule_contours;//轮廓向量vectorVec4i capsule_hierarchy;//拓扑结构变量//参数二值化图轮廓向量拓扑结构变量检测方法发现方法偏移量findContours(new_binary, capsule_contours, capsule_hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(-1, -1));//计算总面积double total_area 0;//白区面积vectorvectorPoint capsule_save;//胶囊子轮廓保存int bubble_num0;//气泡数量变量int black_num 0;//黑点数量变量for (int c 0; c capsule_contours.size(); c) {//循环胶囊轮廓double area contourArea(capsule_contours[c])/10;//计算面积//cout area/10 area endl;if (area 7) {//气泡bubble_num;//气泡数量变量加1//绘制轮廓drawContours(capsule, capsule_contours, c, Scalar(0,0, 255), 1);//面积累加total_area area;}else if(area3){//噪点black_num ;//黑点数量变量//绘制轮廓drawContours(capsule, capsule_contours, c, Scalar(255, 0, 255), 1);//面积累加total_area area;}}//imshow(contours_img, capsule);//判断返回if (bubble_num1 || black_num 1) {//当子轮廓数量有时//给定数据data.classification (bubble_num 0 ? 3 : 4);//当气泡数量大于0时为气泡否则为黑点data.area total_area;//赋值面积return true;//返回真}else {//否则return false;//返回假} }Mydata capsule_processing_funciton(Mat capsule, Mat mask, Matsmall_mask) {//胶囊处理函数,返回胶囊所需数据//定义自定义结构体变量Mydata data;//初始化结构体变量data.classification -1;data.height -1;data.width -1;data.area -1;//1判空if (is_empty_func(mask)) {data.classification 5;//分类赋值5为空data.height 0;//高为0data.width 0;//宽为0}else{//2.否则//判断if (is_alien_func(mask,data)) {//2.1判异形//打印提示cout capsule_processing_funciton:alien shape endl;}else if (is_big_and_small_func(mask,data)) {//2.2判大小端//打印提示cout capsule_processing_funciton:big and small shape endl;}else if (is_bobble_and_blackP_func(capsule, small_mask,data)) {//2.3判气泡或黑点如果是那么问题位置由函数绘制上去cout capsule_processing_funciton:bobble or blackPoint endl;//计算掩码的宽高//发现轮廓vectorvectorPoint contours;//轮廓vectorVec4i hierarchy;//拓扑结构变量//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(mask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));//发现轮廓//获得最小斜矩形RotatedRect rrect minAreaRect(contours[0]);//赋值数据为何防止出现宽高显示不对的情况人为调整一下data.height (rrect.size.heightrrect.size.width? rrect.size.height:rrect.size.width);//高data.width (rrect.size.heightrrect.size.width ? rrect.size.width :rrect.size.height);//宽}else {//否则为正常胶囊cout capsule_processing_funciton:normal capsule endl;//计算掩码的宽高//发现轮廓vectorvectorPoint contours;//轮廓vectorVec4i hierarchy;//拓扑结构变量//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(mask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));//发现轮廓//获得最小斜矩形RotatedRect rrect minAreaRect(contours[0]);//赋值数据为何防止出现宽高显示不对的情况人为调整一下data.height (rrect.size.heightrrect.size.width ? rrect.size.height : rrect.size.width);//高data.width (rrect.size.heightrrect.size.width ? rrect.size.width : rrect.size.height);//宽data.classification 0;//赋值类型0为好品data.area 0;//面积给0}}return data;//返回数据 }void drawCapsule_function(Mat capsule,Matblk_mask, Mat mask, Mat small_mask,Mydata data) {//绘制胶囊掩码//发现大轮廓vectorvectorPoint big_contours;//大轮廓向量vectorVec4i big_hierarchy;//大拓扑结构向量//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(mask,big_contours,big_hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point(-1,-1));//发现小轮廓vectorvectorPoint small_contours;//小轮廓向量vectorVec4i small_hierarchy;//小拓扑结构向量//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(small_mask,small_contours,big_hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point(-1,-1));//根据分类绘制内轮廓和外轮廓if (data.classification 0 data.classification4) {//好品0获得其他1-4的情况//绘制轮廓,好品(0)绘制绿色1-4情况绘制红色drawContours(capsule,big_contours,-1,(data.classification0? Scalar(0, 255, 0): Scalar(0, 0, 255)),1,LINE_AA,big_hierarchy);}else if (data.classification 5) {//空5 //反色掩码处理方便获得轮廓Mat ref_blk_mask;bitwise_not(blk_mask,ref_blk_mask);//发现大轮廓vectorvectorPoint ref_blk_mask_contours;//大轮廓向量vectorVec4i ref_blk_mask_hierarchy;//大拓扑结构向量//参数二值化图轮廓向量检测方法发现方法偏移点偏移点用于大图还原此处未用到findContours(ref_blk_mask, ref_blk_mask_contours, ref_blk_mask_hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(-1, -1));//绘制轮廓,白色drawContours(capsule, ref_blk_mask_contours, -1, Scalar(255, 255, 255), 1, LINE_AA, ref_blk_mask_hierarchy);}else {//坏品-1//绘制轮廓,红色drawContours(capsule, big_contours, -1, Scalar(0, 0, 255), 1, LINE_AA, big_hierarchy);}//绘制内轮廓if (data.classification!5) {//判断不为空//绘制内轮廓蓝色(直线)//drawContours(capsule,small_contours,-1,Scalar(255,0,0),1,LINE_AA,small_hierarchy);//画虚线自定义函数drawDashContours(capsule, small_contours, 0, Scalar(255, 0, 0),1,LINE_AA,5);} }void putText_function(Mat src, Rectpos, Mydata data) {//在图片上写文本//判空if (src.empty()) {//图为空return;//返回}//定义对应类别数组char* class_name[] {bad,good,alien,big_and_small,bubble,black point,empty};//放入文字-类别//参数图文本原点字体缩放比颜色线宽线型底左对齐(倒过来的效果)putText(src,format(%d(%s),data.classification,class_name[data.classification1]),Point(pos.xpos.width/2,pos.y),CV_FONT_NORMAL,0.5,Scalar(255,0,0),1,LINE_AA,false);if(data.classification!5){//当分类不等于空5时绘制文字//放入文字-宽putText(src,format(Width:%d,data.width),Point(pos.x-pos.width/5,pos.y20),CV_FONT_NORMAL,0.5,Scalar(0,255,0),1,LINE_AA,false);//放入文字-高putText(src,format(Height:%d,data.height),Point(pos.x-pos.width/5,pos.y40),CV_FONT_NORMAL,0.5,Scalar(0,255,0),1,LINE_AA,false);//放入文字-面积putText(src,format(Area:%.2f,data.area),Point(pos.x-pos.width/5,pos.y60),CV_FONT_NORMAL,0.5,((data.area0)?Scalar(0,0,255): Scalar(0, 255, 0)),1,LINE_AA,false);} }void drawDashContours(InputOutputArray image, InputArrayOfArrays contours,int contourIdx, const Scalar color,int thinkness1,int lineType8, int gap_threshold10) {//自定义函数实现画虚线轮廓//获得图像引用关系Mat img image.getMat();//定义并获取轮廓总个数int ncontours (int)contours.total();//当轮廓总数量为0或指定轮廓数字大于(总轮廓数-1)时直接返回if (ncontours0|| contourIdx(ncontours-1)) {return;}//定义存储区AutoBufferPoint* _ptsptr(ncontours);//用于存储点的双指针大小与轮廓数一致AutoBufferint _npts(ncontours);//用于存储每个轮廓点的个数的单指针大小与轮廓数一致Point** ptsptr _ptsptr;//获得双指针方便后面添加数据int* npts _npts;//获得单指针方便后面添加数据//判断轮廓标记if (contourIdx 0) {//当轮廓号为-1时循环处理for (int i 0; i ncontours; i) {//循环轮廓位置Mat p contours.getMat(i);//循环获取矩阵引用关系CV_Assert(p.checkVector(2,CV_32S)0);//检查向量个数有条件为假断言判断报错checkVector参数(通道数数据深度)返回向量个数CV_Assert参数:条件ptsptr[i]p.ptrPoint();//赋值当前轮廓获得点指针npts[i] p.rows*p.cols*p.channels() / 2;//赋值点数量行*列*通道数/2}}else {//当轮廓不为-1时指定位置处理Mat p contours.getMat(contourIdx);CV_Assert(p.checkVector(2, CV_32S) 0);//检查向量个数有条件为假断言判断报错checkVector参数(通道数数据深度)CV_Assert参数:条件ptsptr[contourIdx] p.ptrPoint();//赋值当前轮廓获得点指针npts[contourIdx] p.rows*p.cols*p.channels() / 2;//赋值点数量行*列*通道数/2}//循环轮廓数组指针位置和每个轮廓的点个数int threshold (gap_threshold0||gap_threshold15)?10:gap_threshold;//定义间隔阈值,当阈值在0-15之间时使用阈值否则给固定阈值10int counter_threshold[2] {0,0};//阈值计数器用于统计当前是否转化状态,[0]画线统计[1]空统计for (int i 0; i sizeof(ptsptr);i ) {//循环外层指针位置for (int j 0; j npts[i];j) {//循环此层的点个数//判断间隔if(counter_threshold[0]threshold){//当[0]位置统计数小于阈值时,画线//画线,参数图点1点2颜色线宽线型line(img, ptsptr[i][j], ptsptr[i][(j1)% npts[i]], color,thinkness,lineType);//%取余为了确保数据范围counter_threshold[0];//当前状态阈值加1counter_threshold[1] 0;//空阈值为0}else if(counter_threshold[1]threshold){//当[1]位置统计数小于阈值时计数counter_threshold[1];//空阈值阈值加1}else {//否则[0]位置计数统计归0,继续画线counter_threshold[0]0;//当前状态阈值为0//画线,参数图点1点2颜色线宽线型line(img, ptsptr[i][j], ptsptr[i][(j 1) % npts[i]], color,thinkness,lineType);//%取余为了确保数据范围counter_threshold[0];//当前状态阈值加1counter_threshold[1] 0;//空阈值为0}}} } 好的样本模型抠图goodmodel.bmp 实现部分效果 主要思想 1.获得胶囊本身。重点 2.对胶囊进行各种检测。重点 3.对每组胶囊的状态进行组合判断给出结果。 4.给后台或显示结果。 细节说明 1.对于胶囊提取我们需要使用掩码、颜色范围、二值化三个部分完成操作。原因很简单单个算法是无法完成总胶囊提取的。 2.对于胶囊检测来说按照不同检测内容使用不同的方法。其中异型使用凸包形状比较得分处理大小端使用轮廓斜矩阵切半上下两部分形状比较得分处理气泡和黑点使用Canny边缘提取MorphologyEx图像学findContours轮廓完成不同面积的抽取再进行筛选。 3.对于胶囊外部的虚线如何实现使用轮廓向量多个点形成的完整轮廓自己实现绘制轮廓功能因为openCV没有给出画虚线的直接方法。实现思路就是间隔几个点绘制线再间隔几个点不绘线虚线就形成了。 以上程序和说明都是实际测试过的。 需要再优化的内容 1.对于胶囊边缘的提取如何更好的去噪。 2.对于检测点的提取如何更好。 我是Simon 在这里期待与您的交流。
http://www.dnsts.com.cn/news/72601.html

相关文章:

  • PS的网站东莞网站关键词
  • 权威的手机排行榜网站怎样手机做网站教程
  • 九号线香网站建设php 网站开发360
  • 百度网站如何建设微信公众号开发是否需要建立网站
  • 友谊路街道网站建设天眼查登录入口
  • 网站推广策划的思路包括哪些内容去哪个网站有客户找做标书的
  • 找人建设一个网站大概需要多少费用伊犁网站建设
  • 成都户外网站建设怎么建立一个网站?
  • 营销型企业网站wordpress一键生成
  • 网站内容授权书建设网站的行业现状
  • 桂林网站优化注意事项品牌视觉形象设计案例
  • 网站后台管理布局wordpress thesis 开发
  • 做现货黄金的金融网站济南最好的网站制作公司哪家好
  • 深圳品牌网站制作报价福州网站如何制作
  • 杭州电信网站备案wordpress怎么设置语言为中文
  • 菏泽网站制建设哪家好网站建设泽宇
  • 有哪些外贸网站深圳企业管理咨询公司
  • 国外好的室内设计网站分类信息网站建设计划
  • 记事本怎样做网站中信建设有限责任公司电话
  • 免费国外建站新浪网页游戏
  • 网站建设app开发小程序开发含山县建设局网站下载
  • 网站被盗用做网站宣传图的网站
  • 网站音乐播放器插件厦门网站建设团队
  • 网站设计与网页制作正文网站 简约
  • 如何自学网站制作网站建设中国十强
  • 惠州自适应网站建设安阳网红
  • 哈尔滨模板建站公司wordpress显示分类
  • 网站建站加盟wordpress.怎么备份
  • phpcms做网站感想网站模板打包下载
  • 美篇在哪个网站做的网站设计怎么好看