Привет, я новичок в OpenCV. В настоящее время я пытаюсь обнаружить горизонтальные линии на изображении, используя функцию HoughLinesP в opencv, чтобы вычислить соотношение между x и y. Результат обнаружения линии показан на втором рисунке.
Заранее спасибо!
import cv2
import numpy as np
# read image
img = cv2.imread('testtube.png')
# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# apply canny edge detection
edges = cv2.Canny(gray, 90, 100,apertureSize=3)
# get hough lines
result = img.copy()
lines = cv2.HoughLinesP(edges, rho=1,theta=np.pi/2, threshold=30,lines=np.array([]), minLineLength=30,maxLineGap=20)
a,b,c = lines.shape
for i in range(a):
cv2.line(result, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow("edges", edges)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
@ChristophRackwitz, извините, что у меня нет оригинального изображения, но я нашел похожее изображение по ссылке Researchgate.net/figure/…, не могли бы вы объяснить больше, большое спасибо
попробуйте это на своем изображении: profile = gray[:,130]; plt.plot(profile) 130 — координата x столбца пикселей. вероятно, попадет в нужное место, если ширина вашего изображения составляет ~ 260 пикселей. вы должны увидеть сюжетную линию, которая сначала равна 255 (пустая часть), затем что-то среднее, затем почти черное (вниз), затем снова становится белым (вверх). тогда вы можете использовать grad = np.gradient(profile) и построить это на втором графике или на рисунке из двух подграфиков с общей осью X. вы увидите вершины. эти экстремумы можно найти с помощью scipy.signal.find_peaks.
@ by42 У меня есть несколько важных вопросов. Трубка на изображении всегда горизонтальна? Ваше исходное изображение содержит только трубку с белым фоном или оно похоже на то, которым вы поделились в комментариях? Ваша проблема становится намного сложнее или проще в зависимости от ответов.
@ChristophRackwitz, спасибо. Думаю, я понял вашу точку зрения. Резкие изменения стоимости происходят по краям. Я попробую это!
@BarışAktaş Трубка всегда будет располагаться вертикально, я мог бы установить белый фон, чтобы упростить проблему. Просто два слоя жидкости могут быть разного цвета.
Хорошо, тогда, если это так, я думаю, что подход @ChristophRackwitz является лучшим, но вам нужно автоматически найти «координату x столбца пикселей», вы не можете просто написать 130 и предположить, что она всегда будет совпадать с трубкой. Чтобы найти трубку, вы можете снова использовать горизонтальные профили или, возможно, цветовую фильтрацию, если цвет жидкости всегда один и тот же.
дополнительный вопрос: stackoverflow.com/questions/78621736/…





Вот мой подход.
1- Проверьте вертикально все пиксели. Игнорируйте белые пиксели. По вертикали посчитайте черные пиксели (<15), посчитайте другие небелые пиксели. Сохраните эти значения в переменной.
2. Сделайте это для каждого вертикального столбца, который совсем не белый. Для каждого столбца счетчики хранятся в массиве.
3- получить среднее значение всех нечерных и черных пикселей внутри массива. Статистически это даст хорошие результаты.
Для следующего прикладного кода я получаю длину x и y как 273,906, 67,3725 соответственно. Какие результаты являются правильными, если мы проверим вручную.
import cv2
import numpy as np
# Load the image in grayscale
img = cv2.imread('/home/cvlab/Downloads/xy.jpg', cv2.IMREAD_GRAYSCALE)
cv2.namedWindow('Image', cv2.WINDOW_NORMAL)
# Apply median blur
img = cv2.medianBlur(img, 5)
cv2.imshow('Image', img)
# Initialize lists to store counts
cntsUpper = []
cntsLower = []
# Loop through columns
for i in range(img.shape[1]):
cntUpper = 0
cntLower = 0
for j in range(img.shape[0]):
pixel_value = img[j, i]
if 15 < pixel_value < 250:
cntUpper += 1
elif pixel_value < 15:
cntLower += 1
if cntUpper != 0:
cntsUpper.append(cntUpper)
if cntLower != 0:
cntsLower.append(cntLower)
# Calculate the average for lower counts
if cntsLower:
averageLower = sum(cntsLower) / len(cntsLower)
print(f"Average Lower: {averageLower}")
# Calculate the average for upper counts
if cntsUpper:
averageUpper = sum(cntsUpper) / len(cntsUpper)
print(f"Average Upper: {averageUpper}")
cv2.waitKey(0)
cv2.destroyAllWindows()
плохой подход. Хаф — ловушка для новичков. Молот Маслоу. -- пожалуйста, покажите исходное изображение, а не то, на котором вы затемнили окружение. -- создайте столбец размером 1 пиксель посередине изображения. запланируйте это. вот увидишь.