【问题标题】:Calculating center of an object in an image计算图像中对象的中心
【发布时间】:2019-01-28 02:57:49
【问题描述】:

我正在阅读此post 以使用OpenCV 计算图像的中心,而Moments 使用Moments。但我正在尝试计算使用 HoughLinesP 检测到的对象的中心。 OpenCV 有没有办法让我做到这一点?

这是我要为其计算中心的图像。

找到线段,输出图像如下:

import cv2
import numpy as np
import math

img = cv2.imread("./images/octa.jpg")

b,g,r = cv2.split(img)

smoothed = cv2.GaussianBlur(g, (3,3), 0)

edges = cv2.Canny(smoothed, 15, 60, apertureSize = 3)

lines = cv2.HoughLinesP(edges,1,np.pi/180,35, 30, 20)


print("length of lines detected ", lines.shape)


for line in lines:
        for x1,y1,x2,y2 in line:
          cv2.line(img,(x1,y1),(x2,y2),(255,0,0),2)
          print("x1,y1", x1,",",y1, " --- ", "x2,y2", x2,",",y2)



cv2.imshow('detected',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

如何使用坐标计算此图像的中心?我怎么能在这里使用Moments

我的一个限制是我不能使用 OpenCV 中包含的 Contour 方法。

【问题讨论】:

  • 对于特定的图像,裁剪它并只计算质心会更容易,例如使用 scipy。你真的需要从线条中计算出来吗?
  • @user8408080 是的,由于某种原因不能使用 opencv 的轮廓方法。你能告诉我怎么做吗?
  • @user8408080 有什么想法吗?
  • 我目前在手机上,所以我现在无法测试任何东西,但我会在我的电脑上尝试一下
  • 这是唯一需要计算中心的图像吗?还是它们都属于同一类型?

标签: python opencv computer-vision hough-transform


【解决方案1】:

以下代码与cv2 版本的3.3.1 一起使用。

我密切关注opencv docs,它运行良好。

import cv2

img = cv2.imread("octa.jpg", 0)
ret,thresh = cv2.threshold(img,100,255,0)
im2, contours, hierachy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]

M = cv2.moments(cnt)

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

im2 = cv2.cvtColor(im2, cv2.COLOR_GRAY2RGB)

cv2.polylines(im2, cnt, True, (0, 0, 255), 2)

cv2.circle(im2, (cx, cy), 5, (0, 0, 255), 1)

cv2.imshow("res", im2)

两个音符:

  • 您需要将参数0 添加到imread 否则轮廓查找将不起作用
  • 我将阈值设置得稍微低一点,所以只找到了八边形的轮廓

结果:

如果您使用不同版本的cv2,您只需将文档更改为您的版本即可;文档真的很好。

您可能还想稍微模糊一下图像或进行一些其他预处理,但在这种情况下,没有必要这样做。

编辑无轮廓:

我从this post 那里获取了有用的 cmets,并进行了一些修改。这不使用轮廓。它找到线并使用它们来找到中心

import cv2
import numpy as np

mg = cv2.imread('octa.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
ret,thresh = cv2.threshold(blur_gray,100,255,0)

low_threshold = 50
high_threshold = 150
edges = cv2.Canny(thresh, low_threshold, high_threshold)

rho = 1  # distance resolution in pixels of the Hough grid
theta = np.pi / 180  # angular resolution in radians of the Hough grid
threshold = 15  # minimum number of votes (intersections in Hough grid cell)
min_line_length = 50  # minimum number of pixels making up a line
max_line_gap = 50  # maximum gap in pixels between connectable line segments
line_image = np.copy(img) * 0  # creating a blank to draw lines on

# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
                    min_line_length, max_line_gap)

for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),2)

lines_edges = cv2.addWeighted(img, 0.5, line_image, 1, 0)

line_image_gray = cv2.cvtColor(line_image, cv2.COLOR_RGB2GRAY)

M = cv2.moments(line_image_gray)

cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

cv2.circle(lines_edges, (cx, cy), 5, (0, 0, 255), 1)

cv2.imshow("res", lines_edges)

结果: 找到的线用蓝色绘制;红色的中心

【讨论】:

  • 我的一个限制是我不能使用contourOpenCV 方法:(
  • 哦,我想,它只是没有工作,因为你忘了设置参数。我会尝试找到解决方法。所以唯一不允许的功能是cv2.findContours?还是有别的?
  • 可能是在使用 HoughLinesP 识别八边形之后,我可以得到那个部分,然后在上面使用Moments。但我被困在这里了。
  • 任何内部使用 findContours 的方法,例如 cv2.SimpleBlobDetectors cv.cornerHarris, cv2.connectedComponents
  • @Sophia 它将所有检测到的线条绘制成一个空白图像,然后使用cv2.moments 的变体,它以图像而不是点列表作为输入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 2012-11-02
相关资源
最近更新 更多