检测图像中是否存在对象

Detecting presence of an object in an image

本文关键字:存在 对象 是否 图像 检测      更新时间:2023-10-16

我对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文档和其他可能的问题,但我发现没有一个可以解决我的问题。相信我,在我寻求答案的过程中,我在这里和那里磕磕绊绊之后问这个问题。

所以我的问题是——

问题 1.由于我是 C/C++ 的新手(教程代码是用 C++ 编写的),有哪些可能的方法可以在灯亮起或亮起时发出信号?我至少需要在屏幕上显示灯熄灭以及何时重新亮起。我尝试了几种方法,但没有一种奏效。(如果我必须将图像转换为灰度,没关系)(示例 - 指示灯亮起时停止屏幕上显示的消息,关闭时停止显示消息)

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

问题 3.这可能是题外话,但对我的项目至关重要。目前,我正在Windows PC上开发代码,但我打算在Raspberry Pi 3上使用它,它反过来将控制控制电机的从属Arduino UNO板。从我所有的研究中,直到现在,我开始知道RPi上的OpenCV用于python,而我用C/C++编码。那么我可以在 RPi 上运行我的代码,就像在我的 PC 上编写的代码一样,还是我必须首先用 python 重写它,然后将其放在 Pi 上。(哦,如果你能给我进一步的想法,告诉我如何继续我的项目的其余部分,那就太好了!

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

谢谢。

使用 OpenCV 处理库解释投资回报率的示例。您只需下载处理 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();
  }
}

这里有很多问题。为此,您可能最好使用处理或python,因为您需要在Linux的树莓派上使用它。您使用的任何基于 Windows 的头文件或库在 Linux 中都不起作用,除非您运行 ubuntu 在 Linux 中设置 opencv 可能是一个真正的痛苦。处理是跨平台的,并且具有运行的opencv库,并且也被视为arduino代码的扩展,因为语法非常相似。这就是我要开始的地方。

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

为相机中心的停车标志选择一个具有 Inrest"ROI"的区域,一个约占帧中心面积 25-50% 的正方形,然后逐个像素地搜索 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进行比较,则有一个停止标志! 创建一个布尔值,用于查看停车标志,并在为真时处理其余代码。