基于(Python下的OpenCV)图像处理的喷墨墨滴形状规范检测

通过图像处理,分析数码印花的喷头所喷出来的墨滴形状,与标准墨滴形状对比分析,来判断墨水及其喷头设备的状态,由两部分构成

PS:获取墨滴形状照片和标准墨滴形状照片都是手绘的,将就的看吧,主要功能已经实现了,思路也就是这些。
主要思路:
1,首先通过高速摄像头捕获数码印花喷头喷出的墨滴照片
2,将照片进行灰度和二值处理
3,获取照片中墨滴的的边缘
4,获取边缘所围成的墨滴面积
5,对墨滴边缘进行外接圆绘制,并获取外接圆的直径
6,将图片绘制最小外接圆求出面积及其直径
7,将图像和标准墨滴图像进行加权融合,并获取交集部分轮廓图像
8,获取交集部分轮廓面积的大小
9,由以上数据分析,反推出墨水的工艺和喷头设备的状态情况

OpenCV部分

一、将彩色的照片转化为黑色背景、灰度图、二值化

由第一步将拍摄的彩色照片绘制成黑色背景下的二值图
效果如下:在这里插入图片描述

二、获取照片的轮廓(我这里使用的是内轮廓)

import cv2
import numpy as np
from matplotlib import pyplot as plt
from math import sqrtdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/water.png')
show_photo('img ',img )gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[1]draw_img = img.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('res',res)

原图:在这里插入图片描述

捕获内轮廓后的结果:在这里插入图片描述

三、计算密闭轮廓的面积和周长

cv2.arcLength(cnt,True)#轮廓所对应的周长,True表示闭合的
cv2.contourArea(cnt)#第一个轮廓所对应的面积

四、绘制墨滴内轮廓的最小外接圆

x, y, w, h = cv2.boundingRect(cnt)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img_radius = cv2.circle(img,center,radius,(0,255,0),2)#(B,G,R),2为轮廓粗细程度
show_photo('img_radius',img_radius)

墨滴内轮廓的最小外接圆:在这里插入图片描述

五、填充最小外接圆,方便后续求轮廓

img_gray = cv2.cvtColor(img_radius, cv2.COLOR_BGR2GRAY)
_,th = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 寻找轮廓,使用cv2.RETR_CCOMP寻找内外轮廓
img_radius_full, contours, hierarch = cv2.findContours(th, cv2.RETR_CCOMP, 2)
# 找到内层轮廓并填充hierarchy = np.squeeze(hierarch)#使用np.squeeze压缩hierarch的成为一维数据for i in range(len(contours)):# 存在父轮廓,说明是里层if (hierarchy[i][3] != -1):cv2.drawContours(img_radius_full, contours, i, (255, 255, 0), -1)#这里的(255,255,0)代表cyan,也可自定义show_photo('img_radius_full',img_radius_full)        
#cv2.imwrite('E:\Python-workspace\OpenCV\OpenCV/yanyu.jpg', img)

将墨滴内轮廓的最小外接圆填充:
在这里插入图片描述

六、绘制最小外接圆轮廓

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[0]draw_img = img.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('res',res)

墨滴内轮廓的最小外接圆轮廓:
在这里插入图片描述

七、获取最小外接圆面积、周长、直径和半径

#最小外接圆的周长
cv2.arcLength(cnt,True)#轮廓所对应的周长,True表示闭合的#最小外接圆的面积
cv2.contourArea(cnt)#轮廓所对应的面积#最小外接圆直径
cv2.arcLength(cnt,True)/2/3.1415926#最小外接圆直径
sqrt(int(cv2.contourArea(cnt)/3.1415926))

八、与标准墨滴样式进行加权融合

import cv2
import matplotlib.pyplot as plt
import numpy as npimg_1 = cv2.imread('E:\Jupyter_workspace\study\data/water.png')
img_2 = cv2.imread('E:\Jupyter_workspace\study\data/water_img.png')res = cv2.addWeighted(img_1,0.6,img_2,0.4,0)#加权融合
#R = αx + βy + b
#其中x为img_1,y为img_2,α为0.4权重,β为0.6权重,b为0偏移量
#plt.imshow(res)
show_photo('res',res)gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#cnt = contours[5]
cnt = contours[0]
cnt1 = contours[5]draw_img = res.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
res =cv2.drawContours(draw_img,[cnt1],-1,(0,255,0),2)
show_photo('res',res)

标准墨滴:
在这里插入图片描述

获取墨滴与标准墨滴进行加权融合:
在这里插入图片描述

九、绘制获取墨滴图像和标准墨滴图像交集部分轮廓

gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#cnt = contours[5]
cnt = contours[0]
cnt1 = contours[5]draw_img = res.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
res =cv2.drawContours(draw_img,[cnt1],-1,(0,255,0),2)
show_photo('res',res)

获取墨滴和标准墨滴交集轮廓:在这里插入图片描述

十、计算获取墨滴与标准墨滴交集部分面积

cv2.contourArea(cnt)#轮廓所对应的面积
到此,通过opencv已经获取了足够多的数据,由这些数据进行工艺上的对墨水配料反推加工

整合代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from math import sqrtdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()test_img = cv2.imread('E:\Jupyter_workspace\study\data/water.png')#测试图
origin_img = cv2.imread('E:\Jupyter_workspace\study\data/water_img.png')#标准图show_photo('test ',test_img )#测试图像gray = cv2.cvtColor(test_img,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)cnt = contours[0]#1为内轮廓,0为外轮廓draw_img = test_img.copy()
outline =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('outline',outline)#内轮廓length = cv2.arcLength(cnt,True)
area = cv2.contourArea(cnt)
print('轮廓周长为:',length)#轮廓所对应的周长,True表示闭合的
print('轮廓面积为:',area)#轮廓所对应的面积'''
绘制轮廓的最小外接圆
'''
x, y, w, h = cv2.boundingRect(cnt)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
draw_radius_img = test_img.copy()
img_radius = cv2.circle(draw_radius_img,center,radius,(0,255,0),2)#(B,G,R),2为轮廓粗细程度
show_photo('img_radius',img_radius)'''
填充最小外接圆
'''
img_gray = cv2.cvtColor(img_radius, cv2.COLOR_BGR2GRAY)
_,th = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 寻找轮廓,使用cv2.RETR_CCOMP寻找内外轮廓
img_radius_full, contours, hierarch = cv2.findContours(th, cv2.RETR_CCOMP, 2)
# 找到内层轮廓并填充hierarchy = np.squeeze(hierarch)#使用np.squeeze压缩hierarch的成为一维数据for i in range(len(contours)):# 存在父轮廓,说明是里层if (hierarchy[i][3] != -1):cv2.drawContours(img_radius_full, contours, i, (255, 255, 0), -1)#这里的(255,255,0)代表cyan,也可自定义show_photo('img_radius_full',img_radius_full)        r_c = cv2.arcLength(cnt,True)#轮廓所对应的周长,True表示闭合的
r_s = cv2.contourArea(cnt)#轮廓所对应的面积
# c = Π*d = 2*Π*r
# s = Π*r*r
r_d = r_c/3.1415926print('最小外接圆轮廓周长为:',r_c)#轮廓所对应的周长,True表示闭合的
print('最小外接圆轮廓面积为:',r_s)#轮廓所对应的面积
print('最小外接圆轮廓直径为:',r_d)#轮廓所对应的面积'''
与标准墨滴图像进行加权融合
'''
res = cv2.addWeighted(origin_img,0.6,test_img,0.4,0)#加权融合
#R = αx + βy + b
#其中x为img_1,y为img_2,α为0.4权重,β为0.6权重,b为0偏移量
#plt.imshow(res)
show_photo('res',res)gray = cv2.cvtColor(res,cv2.COLOR_BGR2GRAY)#转换为灰度图
ret, thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY)#对图像进行二值处理,小于127为0,大于127为255
binary, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#cnt = contours[0]
cnt1 = contours[5]
#cnt1 = contours[5]draw_mix_img = res.copy()
mix_img =cv2.drawContours(draw_mix_img,[cnt1],-1,(0,0,255),2)
#res =cv2.drawContours(draw_img,[cnt1],-1,(0,255,0),2)
show_photo('mix_img',mix_img)mixed_s = cv2.contourArea(cnt1)#轮廓所对应的面积
mixed_c = cv2.arcLength(cnt1,True)#轮廓所对应的周长,True表示闭合的print('交集轮廓周长为:',mixed_c)#轮廓所对应的周长
print('交集轮廓面积为:',mixed_s)#轮廓所对应的面积
print('\n')if area < 9000 :print('警报:喷头堵塞!!!')
elif mixed_s > 1000 :print("警报:墨水形状不标准!!!")
elif r_d > 110 :print('警报:墨水过于粘稠!!!')
else :print("一切正常")

测试墨滴图像:
在这里插入图片描述
绘制墨滴外轮廓:
在这里插入图片描述
绘制墨滴最小外接圆:
在这里插入图片描述
填充最小外接圆:
在这里插入图片描述
与标准墨滴进行加权融合:
在这里插入图片描述
获取交集部分:
在这里插入图片描述
控制台结果显示:
在这里插入图片描述

墨水工艺部分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微机原理——指令系统——传送类指令(MOV、LEA、LDS、LES、LAHF、SAHF、XCHG、XLAT、PUSH、POP、PUSHF、POPF)

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 【没事儿可以到我主页看看】https://blog.csdn.net/qq_42604176 传送类指令1&…

mysql 任务计划 /etc/cron.d_Linux /etc/cron.d增加定时任务

一般情况下我们添加计划任务时&#xff0c;都是直接修改/etc/crontab。但是&#xff0c;不建议这样做&#xff0c;/etc/cron.d目录就是为了分项目设置计划任务而创建的。例如&#xff0c;增加一项定时的备份任务&#xff0c;我们可以这样处理&#xff1a;在/etc/cron.d目录下新…

19-Harris角点检测

角点检测顾名思义&#xff0c;就是对类似顶点的检测&#xff0c;与边缘有所区别 边缘可能在某一方向上变化不是特别明显&#xff0c;但角点在任何方向上变换都很明显 cv2.cornerHarris(img,blockSize,ksize,k) cv2.cornerHarris(gray,2,3,0.04) 参数一&#xff1a;img&#xff…

微机原理——指令系统——算数运算指令(ADD、ADC、SUB、SBB、INC、DEC、NEG、CMP、MUL、IMUL、DIV、IDIV、CBW、CWD、BCD调整)

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 算数运算指令1、加减法指令ADD、ADC 、SUB 、SBB 和增量减量指令INC、DEC、NEGADD…

20-SIFT算法

import cv2 import numpy as np from matplotlib import pyplot as pltdef show_photo(name,picture):#图像显示函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img cv2.imread(E:\Jupyter_workspace\study\data/cfx.png) gray cv2.cvtColor(img,cv2.COL…

mysql 迁移 nosql_从关系型Mysql到Nosql HBase的迁移实践

2013年11月22-23日&#xff0c;作为国内唯一专注于hadoop技术与应用分享的大规模行业盛会&#xff0c;2013 Hadoop中国技术峰会(China Hadoop Summit 2013)于北京福朋喜来登集团酒店隆重举行。来自国内外各行业领域的近千名CIO、CTO、架构师、IT经理、咨询顾问、工程师、Hadoop…

21-特征匹配方法(Brute-Force蛮力匹配)

Brute-Force蛮力匹配 cv2.BFMatcher(crossCheck True) crossCheck表示两个特征点相互匹配 例如A中的第i个特征点与B中的第j个特征点最近&#xff0c;并且B中的第j个特征点到A中的第i个特征点也是 NORM_L2&#xff1a;归一化数组的(欧几里得距离)&#xff0c;如果其他特征计算…

Opencv——几何空间变换(仿射变换和投影变换)

几何空间变换【1】几何变换&#xff08;空间变换&#xff09;简述【2】变换矩阵知识简述齐次坐标的概念几何运算矩阵【3】图像的仿射变换1、平移变换2、比例缩放3、旋转4、对称变换&#xff08;不做展示&#xff09;1、关于X轴变换2、关于Y轴变换3、关于直线YX变换4、关于直线Y…

probuffer java_Protocol Buffer的使用

Probotbuf简介在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML&#xff0c;这两种技术常被用于数据的结构化呈现和序列化。我们可以从两个方面来看JSON 和 XML与protobuf的异同&#xff1a;一个是数据结构化&#xff0c;一个是数据序列化。这里的数据结构化…

22-随机抽样一致算法RANSAC

随机抽样一致算法(Random sample consensus&#xff0c;RANSAC) 看似复杂&#xff0c;其基本思想就是&#xff1a;随机选取俩点&#xff0c;然后连接&#xff0c;给定一个容忍范围&#xff0c;在这个范围内的点越多越好&#xff0c;然后不断的迭代进行找两点之间容忍范围内点最…

23-背景建模

帧差法 由于场景中的目标在运动&#xff0c;目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧图像进行差分运算&#xff0c;不同帧对应的像素点相减&#xff0c;判断灰度差的绝对值&#xff0c;当绝对值超过一定阈值时&#xff0c;即可判断为运动目标&#xf…

DB2 9 运用开辟(733 考试)认证指南,第 3 部门: XML 数据独霸(4)

议决运用顺序存储和检索 XMLXML 编码字符编码在汗青上&#xff0c;术语 字符集、字符编码 和 码页 都有雷同的意义&#xff1a;一个字符集和一个二进制码集&#xff0c;其中每个码示意一个字符。&#xff08;码页是来自 IBM 的一个术语&#xff0c;示意一个大型主机或 IBM PC 上…

Opencv——霍夫变换以及遇到的一些问题

目录问题1 &#xff1a;颜色空间转换函数参数问题&#xff1a;CV_BGR2GRAY vs CV_GRAY2BGR问题2&#xff1a;cvRound()、cvFloor()、cvCeil()函数用法霍夫变换的含义标准霍夫直线变换霍夫线变换函数参数讲解累计概率霍夫变换霍夫变换圆变换原理和算法步骤&#xff1a;霍夫圆变换…

java ssm如何上传图片_ssm整合-图片上传功能(转)

本文介绍 ssm (SpringSpringMVCMybatis)实现上传功能。以一个添加用户的案例介绍(主要是将上传文件)。一、需求介绍我们要实现添加用户的时候上传图片(其实任何文件都可以)。文件名&#xff1a;以 博客名日期的年月日时分秒毫秒形式命名如 言曌博客2017082516403213.png路径&am…

24-光流估计

光流是空间运动物体在观测成像平面上的像素运动的“瞬间速度”&#xff0c;根据各个像素点的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 亮度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变 小运动&#xff1a;随着时间的…

java公平索非公平锁_java中的非公平锁不怕有的线程一直得不到执行吗

首先来看公平锁和非公平锁&#xff0c;我们默认使用的锁是非公平锁&#xff0c;只有当我们显示设置为公平锁的情况下&#xff0c;才会使用公平锁&#xff0c;下面我们简单看一下公平锁的源码&#xff0c;如果等待队列中没有节点在等待&#xff0c;则占有锁&#xff0c;如果已经…

mybatis.net - 5 嵌入资源与引用资源

在SqlMap.config文件中可以有两种方式引入外部的文件。 一种是通过资源的方式&#xff0c;在文件中表现为 resource&#xff0c;就是引用外部的文件&#xff0c;这里需要保证文件的路径正确。 <sqlMaps><sqlMap resource"Maps/ProductMap.xml"/><sqlM…

图解MySQL数据库的陈列和把持-4

泉源&#xff1a;网海拾贝 填入一些测试数据&#xff1a; 封闭“MySQL Query Browser”&#xff0c;再从头翻开它&#xff0c;切换到testtable表&#xff0c;看到了没有&#xff1f;刚刚输出的中文变成了“&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&am…

非常好友(C++)

Bessie和其他的所有奶牛的耳朵上都戴有一个射频识别&#xff08;RFID&#xff09;序列号码牌。因此农夫John可以机械化地计算他们的数量。很多奶牛都有一个“牛友”。如果奶牛A的序列号的约数之和刚好等于奶牛B的序列号&#xff0c;那么A的牛友就是B。在这里&#xff0c;一个数…

使用快捷键,快到极致

前段时间曾经写过一篇文章&#xff0c;《优秀程序员无他-善假于物也》。其中谈到一点是优秀的程序员必须要能灵活的掌握常用软件的快捷键。对于程序员来说&#xff0c;每天使用时间最长的软件恐怕就是IDE&#xff08;Integrated Development Environment&#xff09;了。如果你…