编辑详情:物体大小与小型苏打罐差不多。相机放置在物体上方,使其具有2D /矩形感觉。相机从角点计算出的朝向/角度是随机的。
只是白色背景上有物体(黑色)。拍摄的质量与Logitech网络摄像头所见到的差不多。
一旦我得到了四个角点,我就会计算中心点。然后将中心点转换为厘米。
我想要关注的是“如何”获取这4个角的问题。您可以在此图像中看到我的暴力方法:图像
在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}
这不是他们正在做的确切音译,但它应该能帮助你。
希望这能帮到你,使用矩阵法获取黑白图像的质心。
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;
}
OpenCV有很多函数可以帮助您实现这一目标。如果您使用C#语言编程,可以下载Emgu.CV作为该库的C#.NET封装。
以下是一些获取所需信息的方法:
像以前一样找到角落 - 例如 "CornerHarris" OpenCV 函数
对图像进行阈值处理并计算重心 - 参见 http://www.roborealm.com/help/Center%20of%20Gravity.php ... 这是我会使用的方法。您甚至可以在COG例程中执行阈值处理。即 cog_x += *imagePtr < 128 ? 255 : 0;
查找图像的矩来给出旋转、重心等信息 - 例如 "Moments" OpenCV 函数。(我没有使用过这个)
(编辑) AForge.NET 库也有角点检测函数以及一个示例项目(MotionDetector)和用于连接网络摄像头的库。我认为这将是最容易的方法,假设您正在使用 Windows 和 .NET。
由于没有人发布完整的OpenCV解决方案,这里提供一个简单的方法:
获取二进制图像。 我们加载图像,将其转换为灰度图像,然后使用Otsu阈值获得二进制图像
查找外轮廓。 我们使用findContours
查找轮廓,然后使用boundingRect
提取边界框坐标
查找中心坐标。 由于我们有轮廓,因此可以使用moments提取轮廓的质心来查找中心坐标
输入图像 ->
输出
Center: (100, 100)
Center: (200, 200)
Center: (300, 300)
总结一下:
在一个纯白背景上给定一个物体,是否有人知道OpenCV是否提供了从捕获的帧中轻松检测对象的功能?
首先获取二进制图像(Canny边缘检测, 简单阈值处理, Otsu阈值处理 或 自适应阈值处理),然后使用 findContours
查找轮廓。要获取边界矩形坐标,可以使用 boundingRect
,它将以 x,y,w,h
的形式给出坐标。要绘制矩形,可以使用 rectangle
进行绘制。这将给出轮廓的四个角点。如果要获取中心点,请使用 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()
在其他机器视觉库中,通常称为blob分析。我还没有使用过OpenCV。