检测图像中对象的存在

时间:2016-03-12 00:12:18

标签: c++ image-processing arduino raspberry-pi2 opencv3.0

我对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岁,所以我也有点外包,但像你这样的人的帮助足以让我继续跑步。

感谢。

2 个答案:

答案 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%是红色,则相机前面会有一个停止标志。

是的,请使用工作代码

来投票

https://www.facebook.com/photo.php?fbid=913451218754261&set=a.138550599577664.26406.100002681733815&type=3&theater

 /**
   * 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值来查看停止符号,以及它何时正确处理其余代码。