Я пытаюсь измерить уровень воды в стеклянном канале, используя OpenCV и Python. Я решил использовать HaughLines в выбранной области интереса и найти средние точки указанных линий, чтобы я мог рассчитать разницу между теми, которые мне нужны, и умножить ее на заданный эталонный размер, который я получу позже. Пока часть, где я нахожу линии, выглядит так:
import cv2
import numpy as np
def midpoint(ptA, ptB, ptC, ptD):
return ((ptA + ptC) * 0.5, (ptB + ptD) * 0.5)
img = cv2.imread("b2924.JPG")
img = cv2.resize(img, None, fx=3/10, fy=3/10)
r = cv2.selectROI("main", img, False, False)
cropped = img[r[1]:(r[1]+r[3]), r[0]:(r[0]+r[2])]
cv2.destroyWindow("main")
imgray = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(imgray, 35, 75)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 75, maxLineGap=1000)
midPoint = []
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(cropped, (x1, y1), (x2, y2), (0, 0, 255), 1)
mP = midpoint(x1, y1, x2, y2)
midPoint.append(mP)
midPoint.sort(key = lambda x: x[1])
img[r[1]:(r[1]+r[3]), r[0]:(r[0]+r[2])] = cropped
print(lines)
print(midPoint)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
В зависимости от выбранного изображения и области интереса я получаю противоречивые результаты. Примеры изображений и где я выбираю ROI:
Обратите внимание, что основание канала начинается там, где достигает клейкая лента. Похоже, я почти никогда не могу найти эту точную линию, потому что как шумно у основания. Прямо сейчас эти пороговые значения без морфологии, кажется, дают лучшие результаты. Я пытался использовать sobel
производную вместо canny
, но получил худшие результаты.
Возможно ли вообще получить точные измерения в этой среде? Это вопрос кодирования или изменения способа съемки или того и другого? В будущем мне, возможно, понадобится отобразить профиль воды во время сильной турбулентности, должен ли я просто отойти от OpenCV для этого, так как шум слишком велик? Любая помощь приветствуется.