我真的很抱歉沒有任何代碼的簡短答案,但我建議你採取輪廓和處理它們。
我不知道你需要確切的東西,所以這裏爲大家介紹兩種方法:
-
一些示例爲你的圖片:
import cv2
import numpy as np
import math
img = cv2.imread('image.png')
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
# filtering red area of hue
redHueArea = 15
redRange = ((hsv[:, :, 0] + 360 + redHueArea) % 360)
hsv[np.where((2 * redHueArea) > redRange)] = [0, 0, 0]
# filtering by saturation
hsv[np.where(hsv[:, :, 1] < 95)] = [0, 0, 0]
# convert to rgb
rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
# select only red grayscaled channel with low threshold
gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY)
gray = cv2.threshold(gray, 15, 255, cv2.THRESH_BINARY)[1]
# contours processing
(_, contours, _) = cv2.findContours(gray.copy(), cv2.RETR_LIST, 1)
for c in contours:
area = cv2.contourArea(c)
if area < 8: continue
epsilon = 0.1 * cv2.arcLength(c, True) # tricky smoothing to a single line
approx = cv2.approxPolyDP(c, epsilon, True)
cv2.drawContours(img, [approx], -1, [255, 255, 255], -1)
cv2.imshow('result', img)
cv2.waitKey(0)
在你的情況下,它的工作完美,但是,正如我已經說過,你需要做的輪廓,更多的工作。
問題是你採取每一行中最高的那個。所以你總是會得到每行一個點。也許你可以基於該值設置閾值(例如,如果Red分量大於100)。您仍然可以獲得其他紅色物體或指向圖像。你也應該考慮藍色和綠色組件的值,例如,白色是(255,255,255),所以它們都是高的。你應該把那些紅色高和其他頻道相當低的值。此外,您可以使用線條檢測算法來過濾其他斑點 – api55
我確實已經做到了這一點(以紅色爲高,但綠色和藍色相當低的像素) – Mirnyy
您也可以嘗試擴張和侵蝕,因爲線條點相當一起,並且噪音點不是。或者嘗試[Hough line transform](http://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html)以僅獲取線條,但我不確定曲線將被檢測到。 – api55