第一步:打开摄像头

void MainWindow::on_OpenCameraBtn_clicked()
{capture = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频if(capture==NULL){qDebug()<<"error!";}timer->start(50);//开始计时,超时则发出timeout()信号,1000为1秒,50毫秒取一帧
}

其中cvCreateCameraCapture()函数中参数表示为摄像头的ID,0表示使用任意一个摄像头,如果电脑有多个摄像头,还需指定ID,返回capture指针,这使得后面可以用从视频流获取帧的办法来处理图像。

第二步:获取图像

    frame = cvQueryFrame(capture);//从摄像头中抓取并返回每一帧// 将抓取到的帧,从IplImage格式转换为QImage格式,rgbSwapped是为了显示效果色彩好一些//QImage::Format_RGB888不同的摄像头用不同的格式。QImage image = QImage((const uchar*)frame->imageData,frame->width, frame->height,QImage::Format_RGB888).rgbSwapped();

此处获取的图像为Mat类型,但是为了显示效果更好,使用rebSwapped()函数,转换为QImage类型,后边黑白二值化后要转换回Mat类型,因为opencv视觉库是对Mat类型的图像操作,或者此处不用转换,灰度处理和黑白二值化都用opencv中的函数。

第三步:灰度处理

for (int i = 0; i < image.width(); i++){for (int j= 0; j < image.height(); j++){QRgb color = image.pixel(i, j);int gray = qGray(color);image.setPixel(i, j, qRgba(gray, gray, gray, qAlpha(color)));}}ui->label_3->setPixmap(QPixmap::fromImage(image));

灰度处理我并没用用opencv库,而是用的加权平均法,符合人眼对颜色的感知,对绿色感知强,对蓝色感知弱,F(i,j) = 0.30R(i,j) + 0.59G(i,j) + 0.11B(i,j)),循环处理每个像素点就可以了。若是使用opencv直接对Mat型图像操作,应该使用函数cvtColor(srcImage,dstImage,CV_BGR2GRAY);

第三步:黑白二值化

   for (int i = 0; i < image.width(); i++){for (int j= 0; j < image.height(); j++){QRgb color = image.pixel(i, j);int gray = qGray(color);if(gray<120){gray=0;}else{gray=255;}image.setPixel(i, j, qRgba(gray, gray, gray, qAlpha(color)));}}

转化为二值化图像代码和灰度处理差不多,只是在循环每个像素点的时候加了个判断,低于阈值归零为纯黑色,高于阈值归255为纯白色。

第四步:滤波

         cv::Mat result1;cv::Mat image1;image1 = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.bits(), image.bytesPerLine());cv::cvtColor(image1, image1, CV_BGR2RGB);//中值滤波cv::Mat medianFilter;cv::Mat medianFilter1;cv::medianBlur (image1,medianFilter1,3);//均值滤波cv::blur(medianFilter1,medianFilter,cv::Size(5,5));

从黑白图像到轮廓需要滤波,否则干扰很大。滤波前,需要将QImage类型的图像转化为Mat类型的图像,使用opencv中Mat()函数即刻完成转换。

我使用了两个滤波,均值滤波模糊图像,中值滤波去掉椒盐噪声,效果还算明显。

第五步:轮廓提取

cv::Canny(medianFilter,result1,150,220);cv::namedWindow("Canny medianFilter");cv::imshow("Canny medianFilter",result1);

使用Canny函数即可完成转换。

函数说明:

第一个参数表示输入图像,必须为单通道灰度图。

第二个参数表示输出的边缘图像,为单通道黑白图。

第三个参数和第四个参数表示阈值,这二个阈值中当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割即如果一个像素的梯度大与上限值,则被认为是边缘像素,如果小于下限阈值,则被抛弃。如果该点的梯度在两者之间则当这个点与高于上限值的像素点连接时我们才保留,否则删除。

第五个参数表示Sobel 算子大小,默认为3即表示一个3*3的矩阵。Sobel 算子与高斯拉普拉斯算子都是常用的边缘算子,详细的数学原理可以查阅专业书籍。

第六步:获取周长与面积

vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours( result1, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );/// 计算矩vector<Moments> mu(contours.size() );for( unsigned int i = 0; i < contours.size(); i++ ){ mu[i] = moments( contours[i], false ); }///  计算中心矩:vector<Point2f> mc( contours.size() );for( unsigned int i = 0; i < contours.size(); i++ ){ mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }cv::Mat drawing = Mat::zeros(result1.size(), CV_8UC3);                                                         //绘制轮廓for (unsigned int i = 0; i< contours.size(); i++){Scalar color = Scalar(255, 0, 0);drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());                         //绘制外层和内层轮廓circle(drawing, mc[i], 4, color, -1, 8, 0);}for (unsigned int i = 0; i< contours.size(); i++){// printf(" 通过m00计算出轮廓[%d]的面积: (M_00) = %.2f \n计算出的面积=%.2f , 长度: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength(contours[i], true));qDebug()<<"通过m00计算出轮廓[%d]的面积: (M_00)"<<mu[i].m00*0.00007194;qDebug()<<"计算出的面积="<<contourArea(contours[i])*0.00007194;qDebug()<<"长度="<<arcLength(contours[i],false)*0.002;S=contourArea(contours[i])*0.00013548;L=arcLength(contours[i],false)*0.01149425;//2cm圆if(L<6.6&&L>=6.8){L=L+0.4;}if(L<6.4&&L>=6.6){L=L-0.3;}if(L<6.4&&L>=6.2){L=L-0.1;}ui->lineEdit_2->setText(QString::number(S));ui->lineEdit->setText(QString::number(L));Scalar color2 = Scalar(255, 255, 0);drawContours(drawing, contours, i, color2, 2, 8, hierarchy, 0, Point());circle(drawing, mc[i], 4, color2, -1, 8, 0);}

opencv函数,直接上手使用,其中我为了更使结果更准确,加了一个2cm圆趋近。

第七步:关闭摄像头

void MainWindow::on_CloseCameraBtn_clicked()
{timer->stop(); //停止取帧cvReleaseCapture(&capture); //释放资源
}

效果图:

总结:1.该软件代码大部分使用opencv视觉库,所有opencv库一定要安装正确,保证函数都能调用,opencv库功能强大,学会使用并了解其中功能的原理会加深对算法的认识,这次看opencv库中的函数原理,基本都是根据数学知识得出来的,所有学好高数还是很有必要的,某宝有卖讲解opencv的书。有时间(有钱)要买一本了解一下。

2.识别误差主要来源与摄像头与平面不平行,导致检测到的图像与实物的二维图像不符,也有其他的方法进行尺寸识别,这次参加比赛有位老师跟我聊药品尺寸测量,工业中药品的尺寸测量精度已经可以达到了百分之99多。测量尝试使用摄像机,能够增加测量精度,还可以用热成像技术测量尺寸。所以1.不能偏安一隅,要多去了解各类产品,开阔眼界。2.做东西要有针对性,把实物的各个性能协调好,要将实物最关键的地方做到行业的中上水平。

基于Qt、opencv的规则工件尺寸识别相关推荐

  1. 基于QT+Opencv的红眼去除

    ** 基于QT+Opencv的红眼去除 ** 最近老师布置了一个讨论专题,是关于红眼去除,对于我一个初学者来说,当然是一脸懵了,不过还好百度上有一些资源可以 参考,在几天的了解下,也是成功完成了. 我 ...

  2. Qt+OpenCV之图片中的人脸识别及人脸抠图

    效果 OpenCV函数知识点 imread() 功能:载入图像 函数原型:Mat cv::imread ( const String & filename, int flags = IMREA ...

  3. 基于 SpringMvc + OpenCV 实现的答题卡识别系统(附源码)

    点击关注公众号,实用技术文章及时了解 java_opencv 项目介绍 OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,它提供了一系列图像处理和计算机视觉方面很多通用算法.是研究图像 ...

  4. python手写答题卡识别_基于 Python OpenCV 的简易答题卡识别

    又有一个多月的时间了呢 = = 刚想起来还欠着一篇文章没写,趁着没忘干净赶紧补上 先上样卡(A4,扫描图片为600dpi) 整体并不是很复杂,但一口气手工切40+张也是够累,所以想办法自己写了个识别程 ...

  5. QT Opencv 图像处理 视频处理 人脸识别

    前言 近期学习了OpenCV的一些函数 然后配合着函数跟QT的一些UI写一个图像跟视频处理跟摄像头处理的一些功能 但是这个主要的一个框架是学习一个视频的 当时主要讲的是一个OpenCV的视频处理的 U ...

  6. 基于qt和opencv实现人脸识别打卡系统

    最近在学习opencv,因此就想着和QT结合起来实现一个人脸识别的系统来.下面我来给大家讲讲这个项目怎么实现的 1.项目源码 https://github.com/SagapoZ/FaceRecogn ...

  7. 基于QT的人脸识别考勤管理系统【二】

    前言: 上一篇我们实现了考勤管理系统的用户考勤打卡系统https://blog.csdn.net/qq_42449351/article/details/99716413,这一篇我将为大家带来这个系统 ...

  8. 基于python opencv人脸识别的签到系统

    基于python opencv人脸识别的签到系统 前言 先看下效果 实现的功能 开始准备 页面的构建 功能实现 代码部分 总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人 ...

  9. python人脸识别opencv_Python基于Opencv来快速实现人脸识别过程详解(完整版)

    前言 随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界. 首先看一下本实验需要的数据集,为 ...

最新文章

  1. 节能信标组比赛过程中直流电源设置
  2. PlanAhead 与时序分析
  3. 关于过滤空格问题(未经测试)
  4. 如何用python创建一个下载网站-用Python下载一个网页保存为本地的HTML文件实例...
  5. 微信登录电脑,手机接收消息仍有提示音设置方法
  6. Shell环境变量以及set,env,export的区别
  7. NiosII中Flash的使用(转)
  8. 用Unity3D实现简单的牧师与魔鬼游戏
  9. ViewGroup的测量及绘制
  10. mysql 导入导出脚本_MySQL导入和导出sql脚本
  11. 深度学习Dubbo系列(入门开篇)
  12. 【jQuery笔记Part1】12-jQuery元素的角标
  13. 【小技巧】程序运行结束后弹窗提醒
  14. 腾讯云TBase分布式数据库安装部署
  15. 微信小程序-后台使用富文本编辑器返回数据,小程序编译富文本编辑器返回的数据
  16. CAD调整十字光标的长度
  17. 基础篇. ARM架构和处理器(3)
  18. html网页载入后焦点,HTML5中,用于指定页面加载后是否自动获取焦点的input属性是 答案:autofocus属性...
  19. python k线顶分型_顶分型和底分型的确认及K线包含处理
  20. matlab实现矩阵拼接

热门文章

  1. 系统规划---方案的制订和改进
  2. MQTT协议 -- 消息报文格式
  3. Android studio 关于页面跳转问题
  4. 扫描线面积并、面积交模板
  5. python-opencv第六期:addWeighted函数详解
  6. AWS Direct Connect配置
  7. CAM350导入rou文件报错‘No header % found,load stopped‘
  8. IE浏览器无法上网设置
  9. mfs 分布式文件系统
  10. 等候·《致我们终将逝去的青春》