我试图检测一些彩色物体的位置,将其发送给机器人。对象是这样的彩色笔记本:
我的方法是单独进行阈值处理以分别找到红色,绿色和蓝色,然后对每个颜色应用Canny
滤镜,然后对每种颜色应用findcontours
,而与其他颜色无关。
我觉得这种思维方式很差,效率很低,所以任何帮助都会受到高度赞赏。
代码是
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2\core\core.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
VideoCapture cap;
cap.open(0);
Mat src,gthreshold,rthreshold,bthreshold,hsv;
Mat ggray, rgray, bgray,gray;
namedWindow("src", CV_WINDOW_AUTOSIZE);
namedWindow("gthreshol", 1);
namedWindow("rthreshol", 1);
namedWindow("bthreshol", 1);
namedWindow("ggray", 1);
namedWindow("rgray", 1);
namedWindow("bgray", 1);
cout << "windows created" << endl;
vector<vector<Point>>gcontours;
vector<vector<Point>>rcontours;
vector<vector<Point>>bcontours;
vector<Vec4i> hierarchy;
while (true)
{
cap.read(src);
if (!cap.isOpened())
{cout << "not opened camera" << endl;}
cvtColor(src, hsv, COLOR_BGR2HSV); // converts the RGB image to HSV
inRange(hsv, Scalar(32, 51, 34), Scalar(100, 250, 138), gthreshold); // finds out the green objects
inRange(hsv, Scalar(148, 49, 0), Scalar(179, 255, 205), rthreshold);
inRange(hsv, Scalar(93, 53, 0), Scalar(157, 255, 123), bthreshold);
erode(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); // noise reduction
dilate(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
dilate(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
erode(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
blur(gthreshold, gthreshold, Size(3, 3));
erode(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); // noise reduction
dilate(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
dilate(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
erode(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
blur(rthreshold, rthreshold, Size(3, 3));
erode(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5))); // noise reduction
dilate(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
dilate(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
erode(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
blur(bthreshold, bthreshold, Size(3, 3));
imshow("gthreshol", gthreshold);
imshow("rthreshol", rthreshold);
imshow("bthreshol", bthreshold);
Canny(gthreshold, ggray, 20, 255, 3);
Canny(rthreshold, rgray, 20, 255, 3);
Canny(bthreshold, bgray, 20, 255, 3);
imshow("ggray", ggray);
imshow("rgray", rgray);
imshow("bgray", bgray);
findContours(ggray, gcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(rgray, rcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
findContours(bgray, bcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for (int i = 0; i < gcontours.size(); i++)
{
int area = contourArea(gcontours[i], false);
if (area > 1000)
{
cout << "green area = " << area << endl; break;
}
cout << "green" << endl;
}
for (int k = 0; k < rcontours.size(); k++)
{
int rarea = contourArea(gcontours[k], false);
if (rarea > 1000) {
cout << "red area = " << rarea << endl; break;
}
}
for (int n = 0; n < rcontours.size(); n++)
{
int barea = contourArea(gcontours[n], false);
if (barea > 100) {
cout << "blue area = " << barea << endl; break;
}
}
imshow("src", src);
if (waitKey(30) == 27)
{
cout << "esc is pressed" << endl;
break;
}
}
cout << "the end :) " << endl;
return(0);
}