python-opencv 定位識別讀表

 

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()

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章