[英]OpenCV - Blob/ Defect/ Anomaly Detection
我做一個家庭項目基本上只是為了好玩,但我遇到的麻煩比預期的要多。 我希望能夠在此示例圖像中找到音高標記。 在此處輸入圖像描述
我已經按照一些教程和事情從某個位置加載圖像並在圖像上運行簡單的 blob 檢測。 我的代碼目前如下->
import cv2
import numpy as np
# Read in the image in grayscale
img = cv2.imread('/home/pi/Downloads/divot1.jpeg', cv2.IMREAD_GRAYSCALE)
params = cv2.SimpleBlobDetector_Params()
params.filterByArea = True
params.minArea = 50
# Determine which openCV version were using
if cv2.__version__.startswith('2.'):
detector = cv2.SimpleBlobDetector(params)
else:
detector = cv2.SimpleBlobDetector_create(params)
# Detect the blobs in the image
keypoints = detector.detect(img)
print(len(keypoints))
# Draw detected keypoints as red circles
imgKeyPoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Display found keypoints
cv2.imshow("Keypoints", imgKeyPoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
我知道使用 openCV 時還有很多圖像處理技術,但我希望有人能指出我正確的方向。 我嘗試了一些方法,比如各種模糊類型,以消除每片草葉的一些“噪音”。 我也嘗試弄亂一些參數,盡管我不確定我使用的參數是否有幫助(最小/最大面積、顏色、凸度)
最終目標是能夠找到圖像中的深褐色異常,並返回該形狀的中心“坐標”。
抱歉,我沒有時間實現它,但是對於這種特殊情況,這樣的事情應該可以工作:
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.inRange(hsv_img, (20,0,0), (40,255,255))
img2 = np.where(mask, np.uint8(255), np.uint8(0))
contours,_ = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
brown_spot = sorted(contours, key=cv2.contourArea, reverse=True)[0]
cv2.drawContours(img, [brown_spot], -1, (255,0,0), 3)
可能有一些我錯過的東西或一些錯誤,但我認為你可以玩弄它並從這里拿走它:)
編輯我忽略了你也想要中心坐標的部分。 如果您想要棕色斑點的質心,請獲取所有 x 坐標的平均 x 坐標和所有 y 坐標的平均 y 坐標。 那應該是您的質心坐標。 如果我沒記錯的話,輪廓上有一個額外的尺寸,您可能需要使用 np.squeeze 將其刪除。 之后,您可以使用 np.mean(brown_spot[:,0]) 獲得 y 坐標(第一列)的平均值,使用 np.mean(brown_spot[:, 1])。 cv2.findContours 只查找周長並且間距不一致,因此您的質心可能有點偏離。 如果你想要一個更准確的質心(或者還要考慮棕色點內的空白區域),你將不得不使用 connectedComponents 而不是 findContours。
還沒有人提到模糊,所以我會的。
草的精細細節相當於噪音,無論您對圖片做什么都會打擾您。 模糊它。
編輯:因為我被要求提供一些參數 - “更少”的方法:
顯着性。
或者好的舊統計數據。
im = cv.imread("green-blurred.jpg")
yuv = cv.cvtColor(im, cv.COLOR_BGR2YCrCb) # or COLOR_BGR2YUV, should work equivalently here
#uv = yuv[:,:,(2,3)]
mean = np.mean(yuv, axis=(0,1))
std = np.std(yuv, axis=(0,1))
#mask = ((yuv - mean) / std >= 4.5).any(axis=2)
# EDIT: there needs to be an abs() on that difference, we want magnitudes, no signs
mask = (np.abs(yuv - mean) / std >= 4.5).any(axis=2)
mask_u8 = mask.astype(np.uint8) * 255
#grayscale = (np.abs(yuv - mean) / std / 5).max(axis=2)
cv.imshow("mask", mask_u8)
cv.waitKey(-1)
不是一個完美的方法,但可能可以調整。
使用任何你喜歡的東西來本地化 blob。 findContours
將是一個簡單的選擇。 使用 cv::moments 獲取一些統計信息,您可以將其轉換為 blob 的質心(質心)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.