简体   繁体   English

在嘈杂的图像上查找对象的位置

[英]Find positions of objects on the noisy image

I have a bunch of images and I need to determine positions of crosses for further transformation of the image and the alignment procedure. 我有一堆图像,我需要确定十字的位置,以进一步变换图像和对齐过程。 The problem is that images are quite noisy and I'm new to all these things of computer vision. 问题在于图像非常嘈杂,而我对计算机视觉的所有这些东西都是陌生的。 Generally, I'm trying to solve the task via opencv and python. 通常,我正在尝试通过opencv和python解决任务。 I have tried several approaches described in the tutorial of opencv library but I did not get the appropriate result. 我已经尝试了opencv库教程中描述的几种方法,但是没有得到合适的结果。

Consider: 考虑: 带有四个十字的灰度图像 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. 我通过findContours函数获得的最佳结果。 I have adopted code from the tutorial and I got: 我已经采用了本教程中的代码,并且得到了:

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');

which results in: 结果是: 找到具有几个轮廓的图像 Now I'm confused with the following steps. 现在,我对以下步骤感到困惑。 How can I define which contour is cross and which is not? 如何定义哪个轮廓是交叉的,哪个不是? What to do with crosses consisting of multiple contours? 如何处理由多个轮廓组成的十字架?

Any help is really appreated! 任何帮助都非常感谢!

A simple way on which you can determine what is a cross and what isn't is by making a bouning box x,y,w,h = cv2.boundingRect(cnt) over each contour and selecting those that have h (height) and w (weight) bigger than treshold you provide. 一种简单的确定交叉点和不交叉点的方法是,在每个轮廓上创建一个绑定框x,y,w,h = cv2.boundingRect(cnt)并选择具有h(高度)和w(重量)大于您提供的阈值。 If you observe the noises on the image arent as big as the crosses. 如果您观察到图像上的噪点与十字架一样大。

I have also made an example on how I would try to tackle such a task. 我还举例说明了我将如何解决这一任务。 You can try denoising the image by performing histogram equalization followed by thresholding with OTSU threshold and performing an opening to the threshold (erosion followed by dilation). 您可以尝试通过执行直方图均衡化,然后使用OTSU阈值进行阈值化并对阈值进行开放(侵蚀然后进行扩张)来对图像进行去噪。 Then you can filter out crosses with height and weight of the contour and then calculate the middle points of every bounding box of the contours that is in the mentioned criteria. 然后,您可以过滤出轮廓的高度和权重的十字,然后计算上述标准中轮廓的每个边界框的中点。 Hope it helps a bit. 希望能有所帮助。 Cheers! 干杯!

Example: 例:

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()

Result: 结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM