检测图像中物体的存在
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% 是红色的,则在相机前面有一个停车标志。
是的,给有工作代码的人投反对票
/**
* 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();
}
}
我对 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% 是红色的,则在相机前面有一个停车标志。
是的,给有工作代码的人投反对票
/**
* 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();
}
}