检测图像中物体的存在

Detecting presence of an object in an image

我对 OpenCV 和 C/C++ 还很陌生(不过一直在 Java 和 C# 中编码)。我正在研究一个检测交通灯和标志(仅限停车标志)的项目(而不是机器人)。现在我在这里找到了一个很棒的教程,并使用了教程中提供的代码来检测红色物体。由于它是可配置的,我可以将它设置为可以很好地看到红绿灯。

Link 到教程- 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;

}

我整晚都在查找 OpenCV 文档和 Whosebug 上的其他可能问题,但我发现 none 解决了我的问题。相信我,在我寻求答案的途中跌跌撞撞之后,我才问这个问题。

所以我的问题是-

Q1。由于我是 C/C++ 的新手(教程代码是用 C++ 编写的),当灯亮或熄灭时,有哪些可能的方式发出信号?我至少需要在屏幕上显示灯熄灭和重新亮起的时间。我尝试了几种方法,但 none 有效。(如果我必须将图像转换为灰度并不重要) (示例 - 灯亮时停止在屏幕上显示消息,灯熄灭时继续显示)

Q2。我如何检测这些迹象并采取适当的措施。这里检测不是什么大问题(有很多可用的教程,我可以管理,但任何提示将不胜感激),根据检测采取行动。

Q3。这可能与主题无关,但对我的项目至关重要。 目前我正在 [=43] 上开发代码=] PC,但我打算在 Raspberry Pi 3 上使用它,这将反过来控制控制电机的从属 Arduino UNO 板。从我所有的研究到现在,我已经知道 RPi 上的 OpenCV 在 python 中使用,而我在 C/C++ 中编码。那么我可以 运行 我的代码,因为它是在我的 PC 上写在 RPi 上的,还是我必须先在 python 中重写它,然后把它放在 Pi 上。(哦,如果你能给我对如何继续我的项目的其余部分有进一步的想法,这将是很棒的!)

我显然不是要你们教我 C++。但是一些关键字或示例代码会很棒。请记住,由于此代码的最终用途是在与 Arduino 接口的 RPi 上,如果您可以将代码保留在该上下文中,那就更好了。否则请回答 Windows,我将以一种或另一种方式修改代码并使其在 RPi 上运行。我是一个完全自学的程序员,我只有 17 岁,所以我也有点外包,但是像你们这样的人的帮助足以让我 运行ning.

谢谢。

这里有很多问题。你可能最好使用处理或 python 因为你需要在 raspberry pi 即 linux 上使用它。您使用的任何基于 windows 的头文件或库都不会在 linux 中工作,除非您 运行ning ubuntu 在 linux 中设置 opencv 可以是真正的痛苦。 Processing 是跨平台的,具有 运行 的 opencv 库,也被视为 arduino 代码的扩展,因为语法非常相似。这就是我要开始的地方。

关于红灯这里有一些简单的步骤

选择一个感兴趣的区域 "roi" 作为停车标志,在相机的中心一个正方形,大约占画面中心的 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 检测到该颜色,则出现停止标志!创建一个布尔值以查看停止标志,并在它为真时处理其余代码。

使用 opencv 处理库解释 roi 的示例。您只需下载 processing 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();
  }
}