python - 如何在 Python OpenCV 中找到轮廓边界框的左上角

标签 python opencv contour robotics object-recognition

我在做什么:我有一个机械臂,我想在一张纸上找到物体的 x,y 坐标。

我能够找到一张纸的轮廓并得到它的尺寸(高,宽)。我想要左上角的坐标,因此当我将对象放置在纸上时,我可以获得相对于该点的图像坐标。从那里我将这些像素坐标转换为 cm,然后我将能够将 x,y 坐标返回到我的机械臂。

问题:我找到轮廓的中心,我认为左上角将是...

中心 x 坐标 - (宽度/2),中心 y 坐标 - (高度/2)

我得到的轮廓框的图片。 enter image description here

*带有我的框的轮廓图片应该位于轮廓的左上角 enter image description here

但是,我得到的坐标超出了我的纸的范围。有没有更简单的方法来找到我的左上角坐标?

代码

class Boundary(object):
def __init__(self, image):
    self.frame = image
    self.DefineBounds()

def DefineBounds(self):

    # convert the image to grayscale, blur it, and detect edges
    # other options are four point detection, white color detection to search for the board?

    gray = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    edged = cv2.Canny(gray, 35, 125)

    # find the contours in the edged image and keep the largest one;
    # we'll assume that this is our piece of paper in the image
    # (cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    th, contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

    c = max(contours, key=cv2.contourArea)

    # compute the bounding box of the of the paper region and return it
    cv2.drawContours(self.frame, c, -1, (0, 255, 0), 3)
    cv2.imshow("B and W", edged)
    cv2.imshow("capture", self.frame)
    cv2.waitKey(0)

    # minAreaRect returns (center (x,y), (width, height), angle of rotation )
    # width = approx 338 (x-direction
    # height = 288.6 (y-direction)

    self.CenterBoundBox = cv2.minAreaRect(c)[0]
    print("Center location of bounding box is {}".format(self.CenterBoundBox))
    CxBBox = cv2.minAreaRect(c)[0][1]
    CyBBox = cv2.minAreaRect(c)[0][0]

    # prints picture resolution
    self.OGImageHeight, self.OGImageWidth = self.frame.shape[:2]
    #print("OG width {} and height {}".format(self.OGImageWidth, self.OGImageHeight))

    print(cv2.minAreaRect(c))
    BboxWidth = cv2.minAreaRect(c)[1][1]
    BboxHeight = cv2.minAreaRect(c)[1][0]

    self.Px2CmWidth = BboxWidth / 21.5  # 1cm = x many pixels
    self.Px2CmHeight = BboxHeight / 18  # 1cm = x many pixels
    print("Bbox diemensions {}  x  {}".format(BboxHeight, BboxWidth))
    print("Conversion values Px2Cm width {}, Px2Cm height {}".format(self.Px2CmWidth, self.Px2CmHeight))

    self.TopLeftCoords = (abs(CxBBox - BboxWidth/2), abs(CyBBox - BboxHeight/2))
    x = int(round(self.TopLeftCoords[0]))
    y = int(round(self.TopLeftCoords[1]))
    print("X AND Y COORDINATES")
    print(x)
    print(y)
    cv2.rectangle(self.frame, (x, y), (x+10, y+10), (0, 255, 0), 3)
    print(self.TopLeftCoords)

    cv2.imshow("BOX",self.frame)
    cv2.waitKey(0)

最佳答案

Finds a rotated rectangle of the minimum area enclosing the input 2D point set.

来自:OpenCV docs

所以你的问题的原因很明显,你的轮廓有轻微的倾斜,所以包围整个轮廓的最小矩形将在下侧超出范围。

自从

contours

仅保存一个点向量(这里讨论的是 C++ 接口(interface)),通过在最大轮廓中搜索具有最低 x 值和最高 y 值的点应该很容易找到左上角。

关于python - 如何在 Python OpenCV 中找到轮廓边界框的左上角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49315960/

相关文章:

python - 在django模板中对forloop.counter进行加法运算

Python 代码有效,但 Eclipse 显示错误 - Syntax error while detecting tuple

c++ - 使用opencv进行颜色序列识别

c - OpenCV 中的肤色检测

java - 使用 JavaCV 库的图像旋转问题

python - 如何从多选 QComboBox 中获取选中的项目?

python - 仅获取图像中的外部轮廓

c++ - OpenCV--如何从低质量的灰度图像中获得更好的手部轮廓?

postgis - 如何在 PostGIS 数据库中存储值网格,以便 GeoServer 可以绘制轮廓?

python - 从 django 查看脚本运行 linux 命令