36

给定一个纯白色背景上的对象,有人知道 OpenCV 是否提供了从捕获的帧中轻松检测对象的功能吗?

我正在尝试定位对象(矩形)的角/中心点。我目前正在这样做的方式是通过蛮力(扫描图像以查找对象)并且不准确。我想知道引擎盖下是否有我不知道的功能。

编辑细节:大小和一个小汽水罐差不多。相机位于对象上方,以赋予其 2D/矩形的感觉。来自相机的方向/角度是随机的,它是根据角点计算的。

它只是一个白色背景,上面有对象(黑色)。拍摄的质量与您期望从罗技网络摄像头看到的一样。

一旦我得到角点,我就会计算中心。然后将中心点转换为厘米。

它正在完善我如何获得这 4 个角,这是我想要关注的。你可以用这张图片看到我的蛮力方法:图片

4

5 回答 5

26

已经有一个如何在 OpenCV 中进行矩形检测的示例(查看 samples/squares.c),实际上它非常简单。

这是他们使用的粗略算法:

0. rectangles <- {}
1. image <- load image
2. for every channel:
2.1  image_canny <- apply canny edge detector to this channel
2.2  for threshold in bunch_of_increasing_thresholds:
2.2.1   image_thresholds[threshold] <- apply threshold to this channel
2.3  for each contour found in {image_canny} U image_thresholds:
2.3.1   Approximate contour with polygons
2.3.2   if the approximation has four corners and the angles are close to 90 degrees.
2.3.2.1    rectangles <- rectangles U {contour}

不是他们正在做什么的确切音译,但它应该对您有所帮助。

于 2008-11-26T18:30:23.570 回答
7

希望这会有所帮助,使用矩方法来获取黑白图像的质心。

cv::Point getCentroid(cv::Mat img)
{
    cv::Point Coord;
    cv::Moments mm = cv::moments(img,false);
    double moment10 = mm.m10;
    double moment01 = mm.m01;
    double moment00 = mm.m00;
    Coord.x = int(moment10 / moment00);
    Coord.y = int(moment01 / moment00);
    return Coord;
}
于 2012-09-26T19:25:17.560 回答
4

OpenCV 有很多功能可以帮助您实现这一目标。如果您使用该语言进行编程,请下载 Emgu.CV 以获取包装到库中的 C#.NET。

获得你想要的东西的一些方法:

  1. 像以前一样找到角落 - 例如“CornerHarris”OpenCV函数

  2. 阈值图像并计算重心 - 请参阅http://www.roborealm.com/help/Center%20of%20Gravity.php ...这是我将使用的方法。您甚至可以在 COG 例程中执行阈值处理。即 cog_x += *imagePtr < 128 ?255:0;

  3. 找到图像的时刻以提供旋转、重心等 - 例如“时刻”OpenCV 功能。(这个我没用过)

  4. (编辑)AForge.NET 库具有角点检测功能以及示例项目(MotionDetector)和连接到网络摄像头的库。我认为这将是最简单的方法,假设您使用的是 Windows 和 .NET。

于 2008-11-11T13:43:01.463 回答
1

由于没有人发布完整的 OpenCV 解决方案,这里有一个简单的方法:

  1. 获取二值图像。我们加载图像,转换为灰度,然后使用Otsu的阈值得到二值图像

  2. 寻找外轮廓。我们使用找到轮廓findContours,然后使用提取边界框坐标boundingRect

  3. 找到中心坐标。由于我们有轮廓,我们可以使用找到中心坐标来提取轮廓的质心


这是一个边界框和中心点以绿色突出显示的示例

输入图像->输出

Center: (100, 100)

Center: (200, 200)

Center: (300, 300)

回顾一下:

给定一个纯白色背景上的对象,有人知道 OpenCV 是否提供了从捕获的帧中轻松检测对象的功能吗?

首先获得二值图像(Canny 边缘检测简单阈值Otsu 阈值自适应阈值),然后使用findContours. 要获取边界矩形坐标,您可以使用boundingRectwhich 将为您提供x,y,w,h. 要绘制矩形,您可以使用 绘制它rectangle。这将为您提供轮廓的 4 个角点。如果要获取中心点,请使用 moments提取轮廓的质心

代码

import cv2
import numpy as np

# Load image, convert to grayscale, and Otsu's threshold 
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours and extract the bounding rectangle coordintes
# then find moments to obtain the centroid
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    # Obtain bounding box coordinates and draw rectangle
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)

    # Find center coordinate and draw center point
    M = cv2.moments(c)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])
    cv2.circle(image, (cx, cy), 2, (36,255,12), -1)
    print('Center: ({}, {})'.format(cx,cy))

cv2.imshow('image', image)
cv2.waitKey()
于 2020-01-29T02:05:09.867 回答
0

在其他机器视觉库中通常称为blob分析。我还没用过opencv。

于 2008-11-10T22:56:51.643 回答