OpenCV 物体检测 - 中心点

发布于 2024-07-08 20:48:21 字数 463 浏览 6 评论 0原文

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

我正在尝试定位对象(矩形)的角/中心点。 我目前的做法是通过蛮力(扫描图像中的物体)并且不准确。 我想知道是否有我不知道的功能。

编辑详细信息: 大小与小汽水罐差不多。 相机位于对象上方,给人一种 2D/矩形的感觉。 相机的方向/角度是随机的,是根据角点计算的。

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

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

我正在努力关注的是“如何”获得这四个角球的精炼。 您可以使用此图片查看我的暴力方法:图片

Given an object on a plain white background, does anybody know if OpenCV provides functionality to easily detect an object from a captured frame?

I'm trying to locate the corner/center points of an object (rectangle). The way I'm currently doing it, is by brute force (scanning the image for the object) and not accurate. I'm wondering if there is functionality under the hood that i'm not aware of.

Edit Details:
The size about the same as a small soda can. The camera is positioned above the object, to give it a 2D/Rectangle feel. The orientation/angle from from the camera is random, which is calculated from the corner points.

It's just a white background, with the object on it (black). The quality of the shot is about what you'd expect to see from a Logitech webcam.

Once I get the corner points, I calculate the center. The center point is then converted to centimeters.

It's refining just 'how' I get those 4 corners is what I'm trying to focus on. You can see my brute force method with this image: Image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ㄟ。诗瑗 2024-07-15 20:48:21

已经有一个关于如何在 OpenCV 中进行矩形检测的示例(查看样本/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}

不是他们正在做的事情的精确音译,但它应该对您有帮助。

There's already an example of how to do rectangle detection in OpenCV (look in samples/squares.c), and it's quite simple, actually.

Here's the rough algorithm they use:

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}

Not an exact transliteration of what they are doing, but it should help you.

埋葬我深情 2024-07-15 20:48:21

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

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;
}

Hope this helps, uses the moment method to get the centroid of a black and white image.

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;
}
三生池水覆流年 2024-07-15 20:48:21

OpenCV 有大量函数可以帮助您实现这一目标。 如果您使用 C#.NET 语言进行编程,请下载 Emgu.CV 并将其封装到库中。

获得所需内容的一些方法:

  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。

OpenCV has heaps of functions that can help you achieve this. Download Emgu.CV for a C#.NET wrapped to the library if you are programming in that language.

Some methods of getting what you want:

  1. Find the corners as before - e.g. "CornerHarris" OpenCV function

  2. Threshold the image and calculate the centre of gravity - see http://www.roborealm.com/help/Center%20of%20Gravity.php ... this is the method i would use. You can even perform the thresholding in the COG routine. i.e. cog_x += *imagePtr < 128 ? 255 : 0;

  3. Find the moments of the image to give rotation, center of gravity etc - e.g. "Moments" OpenCV function. (I haven't used this)

  4. (edit) The AForge.NET library has corner detection functions as well as an example project (MotionDetector) and libraries to connect to webcams. I think this would be the easiest way to go, assuming you are using Windows and .NET.

分分钟 2024-07-15 20:48:21

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

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

  2. 查找外部轮廓。我们使用 findContours 查找轮廓code> 然后使用 boundingRect 提取边界框坐标

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


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

输入图像 ->< /code> 输出


Center: (100, 100)


Center: (200, 200)


Center: (300, 300)

回顾一下:

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

首先获取二值图像(Canny边缘检测< /a>, 简单阈值处理, 大津的阈值,或自适应阈值),然后使用 findContours。 要获取边界矩形坐标,可以使用 boundingRect 将为您提供 x,y,w,h 形式的坐标。 要绘制矩形,您可以使用 rectangle 来绘制它。 这将为您提供轮廓的 4 个角点。 如果你想获得中心点,请使用
时刻提取轮廓的质心

代码

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

Since no one has posted a complete OpenCV solution, here's a simple approach:

  1. Obtain binary image. We load the image, convert to grayscale, and then obtain a binary image using Otsu's threshold

  2. Find outer contour. We find contours using findContours and then extract the bounding box coordinates using boundingRect

  3. Find center coordinate. Since we have the contour, we can find the center coordinate using moments to extract the centroid of the contour


Here's an example with the bounding box and center point highlighted in green

Input image -> Output


Center: (100, 100)


Center: (200, 200)


Center: (300, 300)

So to recap:

Given an object on a plain white background, does anybody know if OpenCV provides functionality to easily detect an object from a captured frame?

First obtain a binary image (Canny edge detection, simple thresholding, Otsu's threshold, or Adaptive threshold) and then find contours using findContours. To obtain the bounding rectangle coordinates, you can use boundingRect which will give you the coordinates in the form of x,y,w,h. To draw the rectangle, you can draw it with rectangle. This will give you the 4 corner points of the contour. If you wanted to obtain the center point, use
moments to extract the centroid of the contour

Code

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()
还如梦归 2024-07-15 20:48:21

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

It is usually called blob analysis in other machine vision libraries. I haven't used opencv yet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文