在嘈杂的图像上找到对象的位置
Find positions of objects on the noisy image
我有一堆图像,我需要确定十字的位置以进一步转换图像和对齐程序。问题是图像非常嘈杂,我对计算机视觉的所有这些东西都很陌生。通常,我试图通过 opencv 和 python 解决任务。我尝试了opencv库教程中介绍的几种方法,但没有得到合适的结果。
考虑:I need to determine the exact positions of centers of the crosses (which I can do with about pixel accuracy by hand). The best result I have obtained via findContours
function. I have adopted code from the tutorial 我得到:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import random
random.seed(42)
img = cv.imread("sample.png")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.blur(img_gray, (3,3))
threshold = 150
dst = cv.Canny(img_gray, threshold, threshold * 2)
_, contours, hierarchy = cv.findContours(dst, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
result = np.zeros((dst.shape[0], dst.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (random.randint(0, 256), random.randint(0, 256), random.randint(0, 256))
cv.drawContours(result, contours, i, color, 2, cv.LINE_8, hierarchy, 0)
cv.imwrite("result.png", result)
fig, ax = plt.subplots()
fig.set_size_inches(10, 10);
ax.imshow(result, interpolation='none', cmap='gray');
结果是:现在我对以下步骤感到困惑。如何定义哪个轮廓是交叉的,哪个不是?由多个轮廓组成的十字怎么办?
非常感谢任何帮助!
通过在每个轮廓上制作一个边界框 x,y,w,h = cv2.boundingRect(cnt)
并选择具有 h(高度)和 w(重量)的边界框,您可以通过一种简单的方法来确定什么是十字,什么不是大于您提供的阈值。如果你观察图像上的噪点没有十字那么大。
我还举例说明了我将如何尝试解决这样的任务。您可以尝试通过执行直方图均衡化然后使用 OTSU 阈值进行阈值处理并执行阈值开放(先腐蚀后膨胀)来对图像进行去噪。然后你可以过滤掉轮廓的高度和重量的交叉点,然后计算上述标准中轮廓的每个边界框的中点。希望能有所帮助。干杯!
示例:
import cv2
import numpy as np
img = cv2.imread('croses.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
equ = cv2.equalizeHist(gray)
_, thresh = cv2.threshold(equ,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = np.ones((2,2),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
_, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
if w > 40 and h > 40:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.circle(img,(int(x+(w/2)), int(y+(h/2))),3,(0,0,255),-1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
我有一堆图像,我需要确定十字的位置以进一步转换图像和对齐程序。问题是图像非常嘈杂,我对计算机视觉的所有这些东西都很陌生。通常,我试图通过 opencv 和 python 解决任务。我尝试了opencv库教程中介绍的几种方法,但没有得到合适的结果。
考虑:findContours
function. I have adopted code from the tutorial 我得到:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import random
random.seed(42)
img = cv.imread("sample.png")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.blur(img_gray, (3,3))
threshold = 150
dst = cv.Canny(img_gray, threshold, threshold * 2)
_, contours, hierarchy = cv.findContours(dst, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
result = np.zeros((dst.shape[0], dst.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (random.randint(0, 256), random.randint(0, 256), random.randint(0, 256))
cv.drawContours(result, contours, i, color, 2, cv.LINE_8, hierarchy, 0)
cv.imwrite("result.png", result)
fig, ax = plt.subplots()
fig.set_size_inches(10, 10);
ax.imshow(result, interpolation='none', cmap='gray');
结果是:
非常感谢任何帮助!
通过在每个轮廓上制作一个边界框 x,y,w,h = cv2.boundingRect(cnt)
并选择具有 h(高度)和 w(重量)的边界框,您可以通过一种简单的方法来确定什么是十字,什么不是大于您提供的阈值。如果你观察图像上的噪点没有十字那么大。
我还举例说明了我将如何尝试解决这样的任务。您可以尝试通过执行直方图均衡化然后使用 OTSU 阈值进行阈值处理并执行阈值开放(先腐蚀后膨胀)来对图像进行去噪。然后你可以过滤掉轮廓的高度和重量的交叉点,然后计算上述标准中轮廓的每个边界框的中点。希望能有所帮助。干杯!
示例:
import cv2
import numpy as np
img = cv2.imread('croses.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
equ = cv2.equalizeHist(gray)
_, thresh = cv2.threshold(equ,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = np.ones((2,2),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
_, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
if w > 40 and h > 40:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.circle(img,(int(x+(w/2)), int(y+(h/2))),3,(0,0,255),-1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果: