代码已经完全实现,有点繁琐,由于时间原因,本篇博客我会持续更新补充直到完全补充完毕...
实现步骤:一、墨滴的图像1、捕获标准墨滴图像,对其进行一系列处理,获取其周长circum_origin、面积area_origin
2、捕获测试墨滴图像,对其进行一系列处理,获取其周长circum_test、面积area_test、最小外接圆面积area_test_radius、最小外接圆周长circum_test_radius、最小外接圆直径diameter_test_radius
3、将标准墨滴图像与测试墨滴图像进行加权融合,并获取其交集部分周长circum_intersection、面积area_intersection
4、将这些参数存入到drop数据库下的shape表中,并与墨滴的工艺参数进行主外键关联,墨滴工艺参数主要为:黏度、表面张力
5、通过海量的数据,进行范围查找,即可由墨滴的形状参数确定出墨滴的工艺参数,从而达到我的课题目的。
标准墨滴图像:
测试墨滴图像:
(后续需要对测试图像和原图像进行加权融合操作,故这里需要通过ROI区域获取,指定图像的长宽,我这里使用的长宽为:250*250像素)
标准墨滴预处理后的图像:
测试墨滴预处理后的图像:
我这里使用的是Mysql数据库,数据库名称为drop,里面存放shape表,表中属性分别为:id、circum、area、circum_radius、area_radius、diameter_radius。
| 列名 | 类型即精度 | 数据说明 | 描述 |
|---|---|---|---|
| id | int | primary key、NOT NULL 、AUTO_INCREMENT | 主键,递增,唯一,不为空 |
| circum | decimal(12,4) | 共12位小数数据,其中小数位数4位 | 存放图像的周长数据 |
| area | decimal(12,4) | 共12位小数数据,其中小数位数4位 | 存放图像的面积数据 |
| area_radius | decimal(12,4) | 共12位小数数据,其中小数位数4位 | 存放图像最小外接圆的面积数据 |
| circum_radius | decimal(12,4) | 共12位小数数据,其中小数位数4位 | 存放图像最小外接圆的周长数据 |
| diameter_radius | decimal(12,4) | 共12位小数数据,其中小数位数4位 | 存放图像最小外接圆的直径数据 |
后续表还会进行补充完善...
在drop数据库下创建shape表import pymysql
DBHOST = 'localhost'
DBUSER = 'root'
DBPASS = 'beyond'
DBNAME = 'drop'
DBSET = 'utf8'
try:
conn = pymysql.connect(host = DBHOST,user = DBUSER,password= DBPASS,database= DBNAME,charset= DBSET)#连接drop这个数据库
print('seccessfull!!!')
cur = conn.cursor()
cur.execute("DROP TABLE IF EXISTS shape")#创建water表之前先检查是否存在这个表,若存在则删除
sql = "CREATE TABLE shape(id int primary key NOT NULL AUTO_INCREMENT, circum decimal(12,4), area decimal(12,4), area_radius decimal(12,4), circum_radius decimal(12,4), diameter_radius decimal(12,4))"#创建表
cur.execute(sql)
print('create table seccess!!!')
except pymysql.Error as e:
print('table create is defeated!' + str(e))
import cv2
import numpy as np
import pymysql
from matplotlib import pyplot as plt
from math import sqrt
DBHOST = 'localhost'
DBUSER = 'root'
DBPASS = 'beyond'
DBNAME = 'drop'
DBSET = 'utf8'
def show_photo(name,picture):#图像显示函数
cv2.imshow(name,picture)
cv2.waitKey(0)
cv2.destroyAllWindows()
#显示测试墨滴图像
img_test = cv2.imread('E:Jupyter_workspacestudydata/test.png')
img_origin = cv2.imread('E:Jupyter_workspacestudydata/origin_1.png')
#img_test = cv2.imread('E:Jupyter_workspacestudymysqlimage/4.png')
#img_test = cv2.imread('E:Jupyter_workspacestudydata/a1.png')
show_photo('img_test ',img_test )
show_photo('img_origin ',img_origin )
#将照片转换为灰度图、二值化,获取其轮廓并将轮廓绘制
gray = cv2.cvtColor(img_test,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)
#show_photo('gray',gray)
cnt = contours[0]
draw_img = img_test.copy()
test_outline =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('test_outline',test_outline)
#轮廓周长
circum_test = format(cv2.arcLength(cnt,True), '.4f')
#circum = int(cv2.arcLength(cnt,True))#轮廓所对应的周长,True表示闭合的
print("轮廓周长为:" + circum_test)
#轮廓面积
area_test = format(cv2.contourArea(cnt),'.4f')#轮廓所对应的面积
print("轮廓面积为:" + area_test)
#轮廓最小外接圆
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_test,center,radius,(255,255,255),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寻找内外轮廓
image, 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, contours, i, (255, 255, 255), -1)#这里的(255,255,0)代表cyan,也可自定义
show_photo('radius',img_radius)
img_gray = cv2.cvtColor(img_radius, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 寻找二值化图中的轮廓
image, contours, hierarchy = cv2.findContours(
thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
cv2.drawContours(img_radius, [cnt], 0, (0, 0, 255), 2)
area_test_radius = format(cv2.contourArea(cnt),'.4f')
circum_test_radius = format(cv2.arcLength(cnt,True), '.4f')
diameter_test_radius = format(cv2.arcLength(cnt,True)/3.1416, '.4f')
print("最小外接圆的周长为:");print(circum_test_radius)
print("最小外接圆的面积为:");print(area_test_radius)
print("最小外接圆的直径为:");print(diameter_test_radius)
img_test = cv2.imread('E:Jupyter_workspacestudydata/test.png')
img_origin = cv2.imread('E:Jupyter_workspacestudydata/origin_1.png')
res = cv2.addWeighted(img_test,0.5,img_origin,0.5,0)#加权融合
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]
draw_img = res.copy()
res =cv2.drawContours(draw_img,[cnt],-1,(0,0,255),2)
show_photo('res',res)
img_gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
_,th = cv2.threshold(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(hierarchy)#使用np.squeeze压缩hierarch的成为一维数据
#print(hierarchy.shape)
for i in range(len(contours)):
# 存在父轮廓,说明是里层
if (hierarchy[i]!= -1):
cv2.drawContours(res, contours, i, (255, 255,0), -1)#这里的(255,255,0)代表cyan,也可自定义
show_photo('img_radius_full',img_radius_full)
#轮廓周长
circum_intersection = format(cv2.arcLength(cnt,True), '.4f')#轮廓所对应的周长,True表示闭合的
print("并集轮廓周长为:" + circum_intersection)
#轮廓面积
area_intersection = format(cv2.contourArea(cnt),'.4f')#轮廓所对应的面积
print("并集轮廓面积为:" + area_intersection)
try:
conn = pymysql.connect(host = DBHOST,user = DBUSER,password= DBPASS,database= DBNAME,charset= DBSET)#连接drop这个数据库
print('seccessfull!!!')
cur = conn.cursor()
sql = "INSERT INTO shape(circum,area,area_radius,circum_radius,diameter_radius) VALUE (%s,%s,%s,%s,%s)"#向表中插入数据
value = (circum_test,area_test,area_test_radius,circum_test_radius,diameter_test_radius)
cur.execute(sql,value)
conn.commit()
print('insert seccess!!!')
except pymysql.Error as e:
print('insert is defeated!' + str(e))
conn.rollback()
conn.close()



