【发布时间】:2020-09-29 23:19:51
【问题描述】:
最近我做了我的第一个视觉应用程序。 我的代码可以识别某种颜色的弹珠,并给我这个弹珠的 X、Y、Z 坐标。 为了调试和设置我的系统,我编写了一些代码,我可以轻松地调整和尝试设置。 此代码尝试检测图像中的所有弹珠,并通过用绿点标记来告诉我它认为弹珠在哪里。
基本上我的代码是这样工作的: 我的相机拍照。
它会在一定范围内寻找颜色,并从中制作一个蒙版(范围内为白色,范围外为黑色),如下所示:。
然后我使用houghcircles 命令在此图像中查找圆圈。
我从每个检测到的圆圈中提取中心点并将其放在原始图像上,如下所示:(绿点 = 中心圆圈)
我的检测还有一些问题,但目前我很满意。
现在,我想知道的是:是否可以在每个标记的中心点旁边放置一个百分比,告诉我程序有多确定它是一个圆圈。
如果您有任何其他建议或问题,请随时提出。 我把我的代码放在下面:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <librealsense2/rs.hpp>
using namespace std;
using namespace cv;
Mat image;
Mat imgHSV;
Mat OutputImage;
Mat testframe;
int iLowH = 104;
int iHighH = 111;
int iLowS = 109;
int iHighS = 155;
int iLowV = 120;
int iHighV = 255;
int acc = 1;
int rows = 10;
int para1 = 100;
int para2 = 7;
int minRad = 3;
int maxRad = 14;
static void HSVthreshold(int, int, int, int, int, int, void*)
{
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), OutputImage);
}
static void Circle_detector(int, int, int, int, int, void*)
{
vector<Vec3f> circles;
HoughCircles(OutputImage, circles, HOUGH_GRADIENT, 1,
OutputImage.rows / rows, //change to detect circles that are closer to eachother
para1, para2, minRad, maxRad); //chang last to parameters to detect larger or smaller circles
for (size_t i = 0; i < circles.size(); i++)
{
Vec3i c = circles[i];
Point center = Point(c[0], c[1]);
// circle center
circle(testframe, center, 1, Scalar(0, 255, 0), 2, LINE_AA);
// circle outline
int radius = c[2];
circle(imgHSV, center, radius, Scalar(255, 0, 0), 2, LINE_AA);
}
}
int main()
{
// Contructing piplines and other stuff to receive data from the realsense camera.
//Contruct a pipeline which abstracts the device
rs2::pipeline pipe;
//Create a configuration for configuring the pipeline with a non default profile
rs2::config cfg;
//Add desired streams to configuration
cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_BGR8, 30);
//Instruct pipeline to start streaming with the requested configuration
pipe.start(cfg);
// Camera warmup - dropping several first frames to let auto-exposure stabilize
rs2::frameset frames;
for (int i = 0; i < 30; i++)
{
//Wait for all configured streams to produce a frame
frames = pipe.wait_for_frames();
}
while (waitKey(1) < 0)
{
frames = pipe.wait_for_frames();
//Get each frame
rs2::frame color_frame = frames.get_color_frame();
// Creating OpenCV Matrix from a color image
Mat color(Size(640, 480), CV_8UC3, (void*)color_frame.get_data(), Mat::AUTO_STEP);
// Display in a GUI
if (color.empty())
{
cerr << "image was not generated !" << endl;
return 1;
}
testframe = color;
namedWindow("Display Image", WINDOW_AUTOSIZE);
imshow("Display Image", color);
//convert RGB to HSV
cvtColor(color, imgHSV, COLOR_BGR2HSV);
//Create windows
namedWindow("image", WINDOW_AUTOSIZE); //window for original image
namedWindow("Control", WINDOW_AUTOSIZE); //window for HSV-control sliders
namedWindow("Output", WINDOW_AUTOSIZE); //window for output mask
namedWindow("Control HoughCircles", WINDOW_AUTOSIZE); //window for HoughCircle sliders
namedWindow("Test-window", WINDOW_AUTOSIZE);
//Create trackbars in "Control HSV" window
createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
createTrackbar("HighH", "Control", &iHighH, 179);
createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
createTrackbar("HighS", "Control", &iHighS, 255);
createTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
createTrackbar("HighV", "Control", &iHighV, 255);
int key = 0;
while (key != 27) { // 27 is escape
HSVthreshold(iLowH, iHighH, iLowS, iHighS, iLowV, iHighV, 0);
imshow("Output", OutputImage);
imshow("image", imgHSV);
key = waitKey(1); // wait at most 1 ms for input, if nothing was pressed result is -1
}
//Optional filter --> does not work properly at the moment <--
//morphological opening (remove small objects from the foreground)
erode(OutputImage, OutputImage, getStructuringElement(MORPH_ELLIPSE, Size(1, 1)));
dilate(OutputImage, OutputImage, getStructuringElement(MORPH_ELLIPSE, Size(1, 1)));
//morphological closing (fill small holes in the foreground)
dilate(OutputImage, OutputImage, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
erode(OutputImage, OutputImage, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
imshow("Output", OutputImage);
waitKey();
//Create trackbars in "Control HoughCircles" window
createTrackbar("Distance between detections", "Control HoughCircles", &rows, 50); //detection distance (0 - 50)
createTrackbar("Upper threshold for internal canny edge", "Control HoughCircles", ¶1, 100); //upper threshold for internal canny edge detector (0 - 100)
createTrackbar("threshold for internal canny edge", "Control HoughCircles", ¶2, 50); //threshold for internal canny edge detector (0 - 50)
createTrackbar("Min radius", "Control HoughCircles", &minRad, 200); //minimum circle radius (0 - 200)
createTrackbar("Max radiu", "Control HoughCircles", &maxRad, 200); // maximum circle radius (0 - 200)
int key2 = 0;
while (key2 != 27) { // 27 is escape
Circle_detector(rows, para1, para2, minRad, maxRad, 0);
imshow("image", imgHSV);
imshow("Test-window", testframe);
key2 = waitKey(1); // wait at most 1 ms for input, if nothing was pressed result is -1
}
waitKey();
}
return 0;
}
编辑: 我添加了一些我的测试材料的新图片,遗憾的是,由于光照条件,这并不完全等同于上述情况。
【问题讨论】:
-
1-你能分享源图像给一个机会看看它尝试。 2- 是的,我们可以检查里面的每个圆圈来找出它的绿色百分比。如果你给我源图像。我会试试看。我喜欢 realsense 相机是哪个牌子的
-
你试图消除错误的检测,但也有一些弹珠甚至没有检测到
-
1/2- 遗憾的是我没有上面案例的源图像,这是昨天在一个测试站点。明天早上我会尝试为我的模拟设置拍几张照片,够吗? 3-是的,不是所有的弹珠都被检测到,这是由于 houghcircles 的设置。 4- 我使用的是 Intel realsense D435i
-
好吧,我会等这些照片
-
我添加了一些图片,与真实情况最大的不同是灯光。我希望我今天可以在外面拍一些照片。如果雨停了……
标签: c++ opencv object-detection