二值圖像分析案例精選

提及來,我仍是挺慚愧的,去年四月份連續在51CTO博客發表了一波技術文章,後來由於本身太忙就慢慢忘記更新拉,前兩天一看訪問量竟然突破100+萬拉,感謝各位的厚愛與支持,更以爲51CTO博客改版以後真的是很棒!因此又來更新了!html

最近一直有人向我提問不少二值圖像分析相關的問題,特別選擇了兩個典型的輪廓分析問題。進行分析與編碼實現與演示,廢話很少說,先看第一個問題。算法

問題一

問題描述以下app

想找到工具盤中間缺乏的幾個點,統計出能夠看到的工件數目ide

二值圖像分析案例精選

仔細分析圖像發現,中間都毫無另外的有個白色很亮的圓圈,這個給了我兩個思路工具

  • 能夠經過霍夫變換檢測圓來提取到
  • 能夠經過二值圖像分析來提取 + 輪廓分析來提取到這些點

獲得這些輪廓點以後經過分析整個輪廓區域獲得傾斜角度,進行糾偏,而後經過X與Y投影進行分割,獲得每一個零件的中心位置座標,根據每一行的間隔設置閾值,從而實現缺乏部分部分的標出與件數統計,肯定了這樣的思路之後,我就開始了寫代碼。代碼實現是基於輪廓分析的思路,由於這個方法,用的閾值比較少,有利於算法穩定性檢測。演示各部輸出。二值化處理以後(形態學處理):
二值圖像分析案例精選
輪廓發現與校訂角度以後
二值圖像分析案例精選學習

投影分析與統計結果以下
二值圖像分析案例精選編碼

此外基於霍夫也是能夠嘗試的,霍夫的二值化效果也比較好,顯示以下:
二值圖像分析案例精選
感興趣的同窗能夠本身繼續嘗試下去。code

問題二

描述以下:視頻

如何統計下圖中的對象個數,原圖以下htm

二值圖像分析案例精選
看到這個圖像以後,我的以爲解決十分簡單,基於最外層輪廓發現便可,無需樹形結構與層次分析,集合圖像形態學分析或者距離變換就能夠獲得,最終代碼的運行結果以下:
二值圖像分析案例精選

代碼

問題1的代碼以下(已經添加各步驟註釋了):

src = cv.imread("D:/images/zsxq/zsxq_01.jpg")
cv.imshow("input", src)

# 二值化處理
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, se)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_OTSU | cv.THRESH_BINARY)

# 形態學處理
se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, se)
se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (10, 10))
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, se)
cv.imshow("binary", binary)

# 輪廓分析
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
result = np.zeros_like(binary)
total = 0
for cnt in range(len(contours)):
    area = cv.contourArea(contours[cnt])
    if area < 55:
        continue
    rrt = cv.minAreaRect(contours[cnt])
    cx, cy = rrt[0]
    cv.circle(result, (np.int32(cx), np.int32(cy)), 5, (255), -1)
    total += 1

# 幾何糾偏
h, w = result.shape
pts = []
for row in range(h):
    for col in range(w):
        pv = result[row, col]
        if pv == 255:
            pts.append((col, row))

pts = np.array(pts)
rrt = cv.minAreaRect(pts)
print(rrt)
M = cv.getRotationMatrix2D(((w-1)/2.0,(h-1)/2.0),rrt[2],1)
dst = cv.warpAffine(result,M,(w,h))
src = cv.warpAffine(src,M,(w,h))

# Y方向投影
tbins = y_split(dst)

# X 方向投影
print("y-step", tbins)
for i in range(0, len(tbins), 1):
    if i == 0:
        roi = dst[0:tbins[i], 0:w]
        src_roi = src[0:tbins[i], 0:w, :]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)
    if i == len(tbins)-1:
        roi = dst[tbins[i]:h-1, 0:w]
        src_roi = src[tbins[i]:h-1, 0:w, :]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)
    if 0 < i < (len(tbins)-1):
        roi = dst[tbins[i-1]:tbins[i] - 1, 0:w]
        src_roi = src[tbins[i-1]:tbins[i] - 1, 0:w,:]
        x_projection(roi, src_roi)
        cv.imshow("roi", roi)
        cv.waitKey(0)

# 顯示結果
cv.imshow("result", result)
cv.imshow("dst", dst)
cv.putText(src, "numbers: " + str(total), (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2)
cv.imshow("detection", src)

cv.waitKey(0)
cv.destroyAllWindows()

問題二:

import cv2 as cv
import numpy as np

src = cv.imread("D:/images/zsxq/zsxq_02.jpg")
cv.imshow("input", src)
src = cv.GaussianBlur(src, (3, 3), 0)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
edge = cv.Canny(src, 50, 100)

se = cv.getStructuringElement(cv.MORPH_ELLIPSE, (10, 10))
binary = cv.morphologyEx(edge, cv.MORPH_CLOSE, se)
contours, hireachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
for cnt in range(len(contours)):
    area = cv.contourArea(contours[cnt])
    if area < 100:
        continue
    count += 1
    rrt = cv.minAreaRect(contours[cnt])

    # rotated rectangle
    box = cv.boxPoints(rrt)
    box = np.intp(box)
    cv.drawContours(src, [box], 0, (255, 0, 0), 2)

cv.imshow("binary", binary)
cv.imshow("result", src)
cv.waitKey(0)
cv.destroyAllWindows()

解鎖更多圖像處理與視頻分析技能,
歡迎學習個人最新OpenCV4圖像處理與視頻分析視頻課程

OpenCV4圖像處理與視頻分析 - 實戰教程

感謝你們關注個人博客,我會繼續更新!有大家有動力!

相關文章
相關標籤/搜索