我对OpenCV和C / C ++相当陌生(尽管用Java和C#进行编码)。我正在研究一个项目(机器人),它可以检测交通灯和标志(仅限停车标志)。现在我在这里找到了一个很棒的教程,并使用了教程中提供的代码,因为它用于红色对象检测。由于它是可配置的,我可以设置它以便看到交通信号灯。
指向教程的链接 - http://opencv-srf.blogspot.in/2010/09/object-detection-using-color-seperation.html
这是迄今为止的代码 -
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
VideoCapture cap(0); //capture the video from web cam
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the web cam" << endl;
return -1;
}
namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"
int iLowH = 0;
int iHighH = 179;
int iLowS = 0;
int iHighS = 255;
int iLowV = 0;
int iHighV = 255;
//Create trackbars in "Control" window
cvCreateTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
cvCreateTrackbar("HighH", "Control", &iHighH, 179);
cvCreateTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
cvCreateTrackbar("HighS", "Control", &iHighS, 255);
cvCreateTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
cvCreateTrackbar("HighV", "Control", &iHighV, 255);
while (1)
{
Mat imgOriginal;
bool bSuccess = cap.read(imgOriginal); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
Mat imgHSV;
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
Mat imgThresholded;
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image
//morphological opening (remove small objects from the foreground)
erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
//morphological closing (fill small holes in the foreground)
dilate( imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)) );
imshow("Thresholded Image", imgThresholded); //show the thresholded image
imshow("Original", imgOriginal); //show the original image
if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
我花了一整夜的时间在StackOverflow上查找OpenCV文档和其他可能的问题,但我发现没有解决我的问题。相信我,在我寻求答案之后,我在这里和那里磕磕绊绊地问这个问题。
所以我的问题是 -
Q1。由于我是C / C ++的新手(教程代码是用C ++编写的),有什么方法可以在灯打开时发出信号?我至少需要在屏幕上显示灯光熄灭以及它何时重新亮起。我尝试了几种方法,但都没有用。(如果我必须将图像转换为灰度,那不重要) (示例 - 当灯亮时停止显示屏幕上的信息,关闭时停止显示)
Q2。如何检测标志并采取适当的措施。在这里检测不是一个大问题(很多教程可用,我可以管理,但任何提示将不胜感激),采取行动检测是。
Q3。 这可能不合适,但对我的项目至关重要。 目前我正在开发Windows PC上的代码,但我打算在Raspberry上使用它Pi 3,它将控制一个控制电机的从属Arduino UNO板。从我所有的研究到现在,我已经知道RPi上的OpenCV用于python,而我用C / C ++编写。因此,我可以运行我在RPi上的PC上编写的代码,或者我必须首先在python中重写它然后将它放在Pi上。(哦,如果你能给我进一步的想法如何继续我的项目的其余部分将会很棒!)
我显然不是要求你们都教我C ++。但是一些关键字或示例代码会很棒。请记住,因为这个代码的最终用途是在与Arduino连接的RPi上,如果你能在这种情况下保持代码,那就更好了。否则,请回答关于Windows的问题,我将以某种方式修改代码并使其在RPi上运行。我是一个完全自学成才的程序员而且我只有17岁,所以我也有点外包,但像你这样的人的帮助足以让我继续跑步。
感谢。
答案 0 :(得分:0)
使用opencv处理库解释roi的示例。您只需下载2.0或更高版本的处理,并使用简单的导入工具opencv导入库进行处理。我不打算为你做整个项目。在框架的中心创建一个静态roi,如果在roi中检测到颜色,则在前面有一个停止符号,您可以看到下面的工作代码来检测阈值颜色。
import gab.opencv.*;
PImage src;
OpenCV opencv;
int roiWidth = 300;
int roiHeight = 300;
boolean useROI = true;
void setup() {
src = loadImage("test.jpg");
opencv = new OpenCV(this, src);
size(opencv.width, opencv.height);
}
void draw() {
opencv.loadImage(src);
if (useROI) {
opencv.setROI(mouseX, mouseY, roiWidth, roiHeight);
}
opencv.findCannyEdges(20,75);
image(opencv.getOutput(), 0, 0);
}
// toggle ROI on and off
void keyPressed() {
useROI = !useROI;
if (!useROI) {
opencv.releaseROI();
}
}
答案 1 :(得分:-1)
这里有很多问题。你可能最好使用处理或python,因为你需要在覆盆子pi上使用它,这是linux。您使用的基于Windows的任何头文件或库都不能在Linux中运行,除非您在Linux中运行ubuntu设置opencv真的很痛苦。处理是跨平台的,并且具有运行的opencv库,并且也被视为arduino代码的扩展,因为语法非常相似。这是我要开始的地方。
这里的红灯是一些简单的步骤
选择一个有趣的地区&#34; roi&#34;对于相机中心的停止标志,一个约为框架中心25-50%的正方形,然后逐个像素地搜索roi,颜色为红色。如果roi的x%是红色,则相机前面会有一个停止标志。
是的,请使用工作代码
来投票 /**
* MultipleColorTracking
* Select 2 colors to track them separately
*
* It uses the OpenCV for Processing library by Greg Borenstein
*/
import gab.opencv.*;
import processing.video.*;
import java.awt.Rectangle;
Capture video;
OpenCV opencv;
PImage src;
ArrayList<Contour> contours;
int maxColors = 2;
int[] hues;
int[] colors;
int rangeWidth = 10;
PImage[] outputs;
int colorToChange = -1;
void setup() {
video = new Capture(this, 640, 480);
opencv = new OpenCV(this, video.width, video.height);
contours = new ArrayList<Contour>();
size(opencv.width + opencv.width/4 + 30, opencv.height, P2D);
// Array for detection colors
colors = new int[maxColors];
hues = new int[maxColors];
outputs = new PImage[maxColors];
video.start();
}
void draw() {
background(150);
if (video.available()) {
video.read();
}
// <2> Load the new frame in to OpenCV
opencv.loadImage(video);
// Tell OpenCV to use color information
opencv.useColor();
src = opencv.getSnapshot();
// <3> Tell OpenCV to work in HSV color space.
opencv.useColor(HSB);
detectColors();
// Show images
image(src, 0, 0);
for (int i=0; i<outputs.length; i++) {
if (outputs[i] != null) {
image(outputs[i], width-src.width/4, i*src.height/4, src.width/4, src.height/4);
noStroke();
fill(colors[i]);
rect(src.width, i*src.height/4, 30, src.height/4);
}
}
// Print text if new color expected
textSize(20);
stroke(255);
fill(255);
if (colorToChange > -1) {
text("click to change color " + colorToChange, 10, 25);
} else {
text("press key [1-2] to select color", 10, 25);
}
displayContoursBoundingBoxes();
}
//////////////////////
// Detect Functions
//////////////////////
void detectColors() {
for (int i=0; i<hues.length; i++) {
if (hues[i] <= 0) continue;
opencv.loadImage(src);
opencv.useColor(HSB);
// <4> Copy the Hue channel of our image into
// the gray channel, which we process.
opencv.setGray(opencv.getH().clone());
int hueToDetect = hues[i];
//println("index " + i + " - hue to detect: " + hueToDetect);
// <5> Filter the image based on the range of
// hue values that match the object we want to track.
opencv.inRange(hueToDetect-rangeWidth/2, hueToDetect+rangeWidth/2);
//opencv.dilate();
opencv.erode();
// TO DO:
// Add some image filtering to detect blobs better
// <6> Save the processed image for reference.
outputs[i] = opencv.getSnapshot();
}
if (outputs[0] != null) {
opencv.loadImage(outputs[0]);
contours = opencv.findContours(true,true);
}
}
void displayContoursBoundingBoxes() {
for (int i=0; i<contours.size(); i++) {
Contour contour = contours.get(i);
Rectangle r = contour.getBoundingBox();
if (r.width < 20 || r.height < 20)
continue;
stroke(255, 0, 0);
fill(255, 0, 0, 150);
strokeWeight(2);
rect(r.x, r.y, r.width, r.height);
}
}
//////////////////////
// Keyboard / Mouse
//////////////////////
void mousePressed() {
if (colorToChange > -1) {
color c = get(mouseX, mouseY);
println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));
int hue = int(map(hue(c), 0, 255, 0, 180));
colors[colorToChange-1] = c;
hues[colorToChange-1] = hue;
println("color index " + (colorToChange-1) + ", value: " + hue);
}
}
void keyPressed() {
if (key == '1') {
colorToChange = 1;
} else if (key == '2') {
colorToChange = 2;
}
}
void keyReleased() {
colorToChange = -1;
}
在您检测到颜色后,如果您的roi已经检测到颜色,则将其与您的roi进行比较,然后会出现停止标志!创建一个bool值来查看停止符号,以及它何时正确处理其余代码。