import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
"""
函数的格式为:kmeans(data, K, bestLabels, criteria, attempts, flags)
(1)data: 分类数据,最好是np.float32的数据,每个特征放一列。之所以是np.float32原因是这种数据类型运算速度快,同样的数据下如果是uint型数据将会慢死你。
(2) K: 分类数,opencv2的kmeans分类是需要已知分类数的。
(3) bestLabels:预设的分类标签:没有的话 None
(4) criteria:迭代停止的模式选择,这是一个含有三个元素的元组型数。格式为(type,max_iter,epsilon)
其中,type又有两种选择:
—–cv2.TERM_CRITERIA_EPS :精确度(误差)满足epsilon停止。
—- cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过max_iter停止。
—-cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,两者合体,任意一个满足结束。
(5)attempts:重复试验kmeans算法次数,将会返回最好的一次结果
(6)flags:初始类中心选择,两种方法
cv2.KMEANS_PP_CENTERS ; cv2.KMEANS_RANDOM_CENTERS
"""
def panelAbstract(srcImage):
imgHeight,imgWidth = srcImage.shape[:2]
imgHeight = int(imgHeight);imgWidth = int(imgWidth)
# 均值聚类提取前景:二维转一维
imgVec = np.float32(srcImage.reshape((-1,3)))
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER,10,1.0)
flags = cv2.KMEANS_RANDOM_CENTERS
ret,label,clusCenter = cv2.kmeans(imgVec,2,None,criteria,10,flags)
clusCenter = np.uint8(clusCenter)
clusResult = clusCenter[label.flatten()]
imgres = clusResult.reshape((srcImage.shape))
imgres = cv2.cvtColor(imgres,cv2.COLOR_BGR2GRAY)
bwThresh = int((np.max(imgres)+np.min(imgres))/2)
_,thresh = cv2.threshold(imgres,bwThresh,255,cv2.THRESH_BINARY_INV)
threshRotate = cv2.merge([thresh,thresh,thresh])
# 确定前景外接矩形
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
minvalx = np.max([imgHeight,imgWidth]);maxvalx = 0
minvaly = np.max([imgHeight,imgWidth]);maxvaly = 0
maxconArea = 0;maxAreaPos = -1
for i in range(len(contours)):
if maxconArea < cv2.contourArea(contours[i]):
maxconArea = cv2.contourArea(contours[i])
maxAreaPos = i
objCont = contours[maxAreaPos]
# 旋转校正前景
rect = cv2.minAreaRect(objCont)
for j in range(len(objCont)):
minvaly = np.min([minvaly,objCont[j][0][0]])
maxvaly = np.max([maxvaly,objCont[j][0][0]])
minvalx = np.min([minvalx,objCont[j][0][1]])
maxvalx = np.max([maxvalx,objCont[j][0][1]])
if rect[2] <=-45:
rotAgl = 90 +rect[2]
else:
rotAgl = rect[2]
if rotAgl == 0:
panelImg = srcImage[minvalx:maxvalx,minvaly:maxvaly,:]
else:
rotCtr = rect[0]
rotCtr = (int(rotCtr[0]),int(rotCtr[1]))
rotMdl = cv2.getRotationMatrix2D(rotCtr,rotAgl,1)
imgHeight,imgWidth = srcImage.shape[:2]
#图像的旋转
dstHeight = math.sqrt(imgWidth *imgWidth + imgHeight*imgHeight)
dstRotimg = cv2.warpAffine(threshRotate,rotMdl,(int(dstHeight),int(dstHeight)))
dstImage = cv2.warpAffine(srcImage,rotMdl,(int(dstHeight),int(dstHeight)))
dstRotimg = cv2.cvtColor(dstRotimg,cv2.COLOR_BGR2GRAY)
_,dstRotBW = cv2.threshold(dstRotimg,127,255,0)
contours, hierarchy = cv2.findContours(dstRotBW,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
maxcntArea = 0;maxAreaPos = -1
for i in range(len(contours)):
if maxcntArea < cv2.contourArea(contours[i]):
maxcntArea = cv2.contourArea(contours[i])
maxAreaPos = i
x,y,w,h = cv2.boundingRect(contours[maxAreaPos])
#提取前景:panel
panelImg = dstImage[int(y):int(y+h),int(x):int(x+w),:]
panel_img = cv2.imwrite('image2/panel_img.png', panelImg) # 将画上矩形的图形保存到当前目录
# cv2.imshow("img", img)
# cv2.imshow("mask", mask)
# cv2.imshow("target", target)
cv2.imshow("panel_img", panel_img)
return panelImg
def getTaeget(targetImg):
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
HSV = cv2.cvtColor(targetImg, cv2.COLOR_BGR2HSV) # 把BGR图像转换为HSV格式
Lower = np.array([0, 3, 5]) # 要识别颜色-红色的下限 ## 0 5 5 10 255 255
Upper = np.array([10, 255, 255]) # 要识别的颜色-红色的上限
# mask是把HSV图片中在颜色范围内的区域变成白色,其他区域变成黑色
mask = cv2.inRange(HSV, Lower, Upper)
erosion = cv2.erode(mask, kernel_4, iterations=1)
erosion = cv2.erode(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)
# target是把原图中的非目标颜色区域去掉剩下的图像
target = cv2.bitwise_and(targetImg, targetImg, mask=dilation)
# 将滤波后的图像变成二值图像放在binary中
ret, binary = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY)
# 在binary中发现轮廓,轮廓按照面积从小到大排列
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
w_ = []
for i in contours: # 遍历所有的轮廓
x1, y1, w, h = cv2.boundingRect(i) # 将轮廓分解为识别对象的左上角坐标和宽、高
w_.append(w)
i = w_.index(max(w_))
x, y, w, h = cv2.boundingRect(contours[i])
# cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255,), 3)
cropped = targetImg[y - 480:y + 380, x - 190:x + 280] # 裁剪坐标为[y0:y1, x0:x1]
# cv_cut_img_circle = cv2.imwrite("image/cv_cut_img_circle.png", cropped)
# print(x, y, w, h)
target_img = cv2.imwrite('image2/target_img.png', cropped) # 将画上矩形的图形保存到当前目录
# cv2.imshow("img", img)
# cv2.imshow("mask", mask)
# cv2.imshow("target", target)
cv2.imshow("target_img", target_img)
# cv2.waitKey(600)
return cropped
def getGuage(cicleImg):
gaus = cv2.GaussianBlur(cicleImg, (3, 3), 0)
gray_img = cv2.cvtColor(gaus, cv2.COLOR_BGR2GRAY)
gradx = cv2.Sobel(gray_img, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(gray_img, cv2.CV_16SC1, 0, 1)
canny_img = cv2.Canny(gradx, grady, 50, 200) # 黑白的边缘 高低阈值比值为2:1或3:1最佳(50:150 = 1:3)
ret_2, binary_2 = cv2.threshold(canny_img, 127, 255, cv2.THRESH_BINARY)
contours_2, hierarchy_2 = cv2.findContours(binary_2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
h_2_ = []
for j in contours_2: # 遍历所有的轮廓
x1_2, y1_2, w_2, h_2 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
h_2_.append(h_2)
j = h_2_.index(max(h_2_))
# print(max(h_))
# h_2_ = (float(max(h_2_))) * 0.878
# print(max(h_))
# print("h_2_=", h_2_)
x_2, y_2, w_2, h_2 = cv2.boundingRect(contours_2[j])
print("x_2, y_2, w_2, h_2=",x_2, y_2, w_2, h_2)
print("h_2 = ",h_2)
cv2.rectangle(cicleImg, (x_2, y_2), (x_2 + w_2, y_2 + h_2), (0, 255,), 3)
# cropped = cicleImg[(y_2 - 228):(y_2 + 118), (x_2 - 112):(x_2 - 80)] # 裁剪坐标为[y0:y1, x0:x1]
cropped = cicleImg[(y_2):(y_2 + h_2), (x_2):(x_2 + w_2)]
cv_cut_guage = cv2.imwrite("image2/cv_cut_guage.png", cropped)
cv2.imshow("cicleImg", cicleImg)
# cv2.imshow("mask", mask)
# cv2.imshow("target", target)
cv2.imshow("canny_img", canny_img)
cv2.imshow("cv_cut_guage", cv_cut_guage)
return cropped
if __name__=="__main__":
srcImage = cv2.imread('image_guage/DSC_1394.JPG')
#####040 400 145 235(error) 1394 1361(error) 035(error)
# srcImage = cv2.imread('image2/1576638923.jpg')
panelImg = panelAbstract(srcImage)
targetImg = getTaeget(panelImg)
cut_guage = getGuage(targetImg)
gray_img = cv2.cvtColor(cut_guage, cv2.COLOR_BGR2GRAY)
gaus = cv2.GaussianBlur(gray_img, (3, 3), 0)
gradx = cv2.Sobel(gray_img, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(gray_img, cv2.CV_16SC1, 0, 1)
canny_img = cv2.Canny(gradx, grady, 50, 300) # 黑白的边缘 高低阈值比值为2:1或3:1最佳(50:150 = 1:3)
ret_2, binary_2 = cv2.threshold(canny_img, 127, 255, cv2.THRESH_BINARY)
contours_2, hierarchy_2 = cv2.findContours(binary_2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#
h_2_ = []
for j in contours_2: # 遍历所有的轮廓
x1_2, y1_2, w_2, h_2 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
h_2_.append(h_2)
j = h_2_.index(max(h_2_))
# print(max(h_))
h_2_ = (float(max(h_2_))) * 0.878
# print(max(h_2_))
print("h_2_=", h_2_)
# x_2, y_2, w_2, h_2 = cv2.boundingRect(contours_2[j])
# print(x, y, w, h)
# cropped = cut_guage[(y_2 - 228):(y_2 + 115), (x_2 - 108):(x_2 - 80)] # 裁剪坐标为[y0:y1, x0:x1]
# cv_cut_guage = cv2.imwrite("image/cv_cut_guage4.png", cropped)
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
HSV = cv2.cvtColor(cut_guage, cv2.COLOR_BGR2HSV) # 把BGR图像转换为HSV格式
Lower = np.array([0, 10, 10]) # 要识别颜色-红色的下限 ## 0 5 5 10 255 255
Upper = np.array([30, 255, 255]) # 要识别的颜色-红色的上限
mask = cv2.inRange(HSV, Lower, Upper)# mask是把HSV图片中在颜色范围内的区域变成白色,其他区域变成黑色
# erosion = cv2.erode(mask, kernel_4, iterations=1)
# erosion = cv2.erode(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(mask, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)
# target是把原图中的非目标颜色区域去掉剩下的图像
# target = cv2.bitwise_and(img, img, mask=dilation)
# 将滤波后的图像变成二值图像放在binary中
ret_3, binary_3 = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY)
# 在binary中发现轮廓,轮廓按照面积从小到大排列
contours_3, hierarchy_3 = cv2.findContours(binary_3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
w_3_ = []
for j in contours_3: # 遍历所有的轮廓
x1_3, y1_3, w_3, h_3 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
w_3_.append(w_3)
j = w_3_.index(max(w_3_))
x_3, y_3, w_3, h_3 = cv2.boundingRect(contours_3[j])
# cv2.rectangle(cut_guage, (x_3, y_3), (x_3 + w_3/2, y_3 + h_3/2), (0, 255,), 3)
cv2.rectangle(cut_guage, (x_3, y_3), (x_3+ w_3, y_3 + h_3), (255, 0,0), 3)
# srcImage = cv2.imwrite("image2/srcImage.png", srcImage)
youwei = y_3+h_3/2
print("youwei=",youwei)
result = (1-(youwei/h_2_))*100
print("************************************* ")
print("result = ",result)
cv2.namedWindow('srcImage', cv2.WINDOW_NORMAL) # 窗口大小可以改变
cv2.imshow("srcImage", srcImage)
cv2.imshow("cut_guage", cut_guage)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果显示:
分步骤实现:test1file:/F:/code/python/wk_guage/image2/DSC_1394.JPG
前景背景分割:keanmes
原图如下所示:
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
srcImage = cv2.imread('image2/image2/DSC_1400_0000040.JPG')
#srcImage = cv2.imread('image2/guage_1.jpg')
imgHeight, imgWidth = srcImage.shape[:2]
imgHeight = int(imgHeight);
imgWidth = int(imgWidth)
# 均值聚类提取前景:二维转一维
imgVec = np.float32(srcImage.reshape((-1, 3)))
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
flags = cv2.KMEANS_RANDOM_CENTERS
ret, label, clusCenter = cv2.kmeans(imgVec, 2, None, criteria, 10, flags)
clusCenter = np.uint8(clusCenter)
clusResult = clusCenter[label.flatten()]
imgres = clusResult.reshape((srcImage.shape))
imgres = cv2.cvtColor(imgres, cv2.COLOR_BGR2GRAY)
bwThresh = int((np.max(imgres) + np.min(imgres)) / 2)
_, thresh = cv2.threshold(imgres, bwThresh, 255, cv2.THRESH_BINARY_INV)
threshRotate = cv2.merge([thresh, thresh, thresh])
# 确定前景外接矩形
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
minvalx = np.max([imgHeight, imgWidth]);
maxvalx = 0
minvaly = np.max([imgHeight, imgWidth]);
maxvaly = 0
maxconArea = 0;
maxAreaPos = -1
for i in range(len(contours)):
if maxconArea < cv2.contourArea(contours[i]):
maxconArea = cv2.contourArea(contours[i])
maxAreaPos = i
objCont = contours[maxAreaPos]
# 旋转校正前景
rect = cv2.minAreaRect(objCont)
for j in range(len(objCont)):
minvaly = np.min([minvaly, objCont[j][0][0]])
maxvaly = np.max([maxvaly, objCont[j][0][0]])
minvalx = np.min([minvalx, objCont[j][0][1]])
maxvalx = np.max([maxvalx, objCont[j][0][1]])
if rect[2] <= -45:
rotAgl = 90 + rect[2]
else:
rotAgl = rect[2]
if rotAgl == 0:
panelImg = srcImage[minvalx:maxvalx, minvaly:maxvaly, :]
else:
rotCtr = rect[0]
rotCtr = (int(rotCtr[0]), int(rotCtr[1]))
rotMdl = cv2.getRotationMatrix2D(rotCtr, rotAgl, 1)
imgHeight, imgWidth = srcImage.shape[:2]
# 图像的旋转
dstHeight = math.sqrt(imgWidth * imgWidth + imgHeight * imgHeight)
dstRotimg = cv2.warpAffine(threshRotate, rotMdl, (int(dstHeight), int(dstHeight)))
dstImage = cv2.warpAffine(srcImage, rotMdl, (int(dstHeight), int(dstHeight)))
dstRotimg = cv2.cvtColor(dstRotimg, cv2.COLOR_BGR2GRAY)
_, dstRotBW = cv2.threshold(dstRotimg, 127, 255, 0)
contours, hierarchy = cv2.findContours(dstRotBW, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
maxcntArea = 0;
maxAreaPos = -1
for i in range(len(contours)):
if maxcntArea < cv2.contourArea(contours[i]):
maxcntArea = cv2.contourArea(contours[i])
maxAreaPos = i
x, y, w, h = cv2.boundingRect(contours[maxAreaPos])
# 提取前景:panel
panelImg = dstImage[int(y):int(y + h), int(x):int(x + w)]
# cropped = targetImg[y - 150:y + 50, x - 80:x + 80] # 裁剪坐标为[y0:y1, x0:x1]
panel_img = cv2.imwrite("image2/panelImg.png", panelImg)
cv2.imshow("panelImg", panel_img)
test2:从分割所得图像中,根据颜色特识别最大的颜色矩形,(这个表里面一定是某个液位标志)。
panelImg如下图所示:
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
# targetImg = cv2.imread('image/1.jpg')
targetImg = cv2.imread('image/1.jpg')
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
HSV = cv2.cvtColor(targetImg, cv2.COLOR_BGR2HSV) # 把BGR图像转换为HSV格式
Lower = np.array([0, 3, 5]) # 要识别颜色-红色的下限 ## 0 5 5 10 255 255
Upper = np.array([10, 255, 255]) # 要识别的颜色-红色的上限
# mask是把HSV图片中在颜色范围内的区域变成白色,其他区域变成黑色
mask = cv2.inRange(HSV, Lower, Upper)
erosion = cv2.erode(mask, kernel_4, iterations=1)
erosion = cv2.erode(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)
# target是把原图中的非目标颜色区域去掉剩下的图像
target = cv2.bitwise_and(targetImg, targetImg, mask=dilation)
# 将滤波后的图像变成二值图像放在binary中
ret, binary = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY)
# 在binary中发现轮廓,轮廓按照面积从小到大排列
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# w_ = []
#
# for i in contours: # 遍历所有的轮廓
# x1, y1, w, h = cv2.boundingRect(i) # 将轮廓分解为识别对象的左上角坐标和宽、高
# w_.append(w)
# i = w_.index(max(w_))
# x, y, w, h = cv2.boundingRect(contours[i])
# cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255,), 3)
# cropped = targetImg[y - 150:y + 50, x - 80:x + 80] # 裁剪坐标为[y0:y1, x0:x1]
# cv_cut_img_circle = cv2.imwrite("image2/cv_cut_img_circle.png", cropped)
# print(x, y, w, h)
# cv2.imwrite('image/cv_cut_img_circle.png', cv_cut_img) # 将画上矩形的图形保存到当前目录
cv2.drawContours(targetImg, contours, -1, (0, 0, 255), 3)
cv2.imshow("img", targetImg)
cv2.imshow("mask", mask)
cv2.imshow("target", target)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)
cv2.waitKey()
# cv2.imshow("cv_cut_img_circle", cv_cut_img_circle)
# return cropped
test3:在框出的最大矩形中,(先验知识,出的最大矩形,一定是液位表的位置),识别其中为一个带有红色标记的矩形,浮标
进一步缩小面积:
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
cicleImg = cv2.imread('image/cv_cut_img_circle1.png')
gaus = cv2.GaussianBlur(cicleImg, (3, 3), 0)
gray_img = cv2.cvtColor(gaus, cv2.COLOR_BGR2GRAY)
gradx = cv2.Sobel(gray_img, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(gray_img, cv2.CV_16SC1, 0, 1)
canny_img = cv2.Canny(gradx, grady, 100, 200) # 黑白的边缘 高低阈值比值为2:1或3:1最佳(50:150 = 1:3)
ret_2, binary_2 = cv2.threshold(canny_img, 127, 255, cv2.THRESH_BINARY)
contours_2, hierarchy_2 = cv2.findContours(binary_2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
h_2_ = []
for j in contours_2: # 遍历所有的轮廓
x1_2, y1_2, w_2, h_2 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
h_2_.append(h_2)
j = h_2_.index(max(h_2_))
# print(max(h_))
# h_2_ = (float(max(h_2_))) * 0.878
# print(max(h_))
# print("h_2_=", h_2_)
x_2, y_2, w_2, h_2 = cv2.boundingRect(contours_2[j])
cv2.rectangle(cicleImg, (x_2, y_2), (x_2+w_2, y_2+h_2), (0, 255,), 3)
print(x_2, y_2, w_2, h_2)
print(h_2)
cropped = cicleImg[(y_2 - 228):(y_2 + 118), (x_2 - 112):(x_2 - 80)] # 裁剪坐标为[y0:y1, x0:x1]
cv_cut_guage = cv2.imwrite("image2/cv_cut_guage5.png", cropped)
cv2.imshow("cicleImg", cicleImg)
cv2.imshow("canny_demo", canny_img)
cv2.imshow("cv_cut_guage", cv_cut_guage)
# return cropped
cv2.waitKey(0)
cv2.destroyAllWindows()
test4:在框出的最大矩形中,(先验知识,出的最大矩形,一定是液位表的位置),识别其中为一个带有红色标记的矩形,浮标,如下图所示image/cv_cut_guage.png
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
cut_guage = cv2.imread('image2/cv_cut_guage.png')
# srcImage = cv2.imread('image/guage_2.png')
gray_img = cv2.cvtColor(cut_guage, cv2.COLOR_BGR2GRAY)
gaus = cv2.GaussianBlur(gray_img, (3, 3), 0)
gradx = cv2.Sobel(gray_img, cv2.CV_16SC1, 1, 0)
grady = cv2.Sobel(gray_img, cv2.CV_16SC1, 0, 1)
canny_img = cv2.Canny(gradx, grady, 100, 300) # 黑白的边缘 高低阈值比值为2:1或3:1最佳(50:150 = 1:3)
ret_2, binary_2 = cv2.threshold(canny_img, 127, 255, cv2.THRESH_BINARY)
contours_2, hierarchy_2 = cv2.findContours(binary_2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
h_2_ = []
for j in contours_2: # 遍历所有的轮廓
x1_2, y1_2, w_2, h_2 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
h_2_.append(h_2)
j = h_2_.index(max(h_2_))
# h_2_ = (float(max(h_2_))) * 0.878
print("h_2_=", h_2_)
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
HSV = cv2.cvtColor(cut_guage, cv2.COLOR_BGR2HSV)
Lower = np.array([0, 5, 5]) # 要识别颜色-红色的下限 ## 0 5 5 10 255 255
Upper = np.array([20, 255, 255]) # 要识别的颜色-红色的上限
mask = cv2.inRange(HSV, Lower, Upper)
dilation = cv2.dilate(mask, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)
ret_3, binary_3 = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY)
contours_3, hierarchy_3 = cv2.findContours(binary_3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
w_3_ = []
for j in contours_3: # 遍历所有的轮廓
x1_3, y1_3, w_3, h_3 = cv2.boundingRect(j) # 将轮廓分解为识别对象的左上角坐标和宽、高
w_3_.append(w_3)
j = w_3_.index(max(w_3_))
x_3, y_3, w_3, h_3 = cv2.boundingRect(contours_3[j])
youwei = y_3 + h_3 / 2
print("youwei=", youwei)
result = (1 - (youwei / h_2_)) * 100
print(result)
# cv2.imshow("canny_img", canny_img)
cv2.waitKey(0)
# cv2.destroyAllWindows()