2016-03-12 1 views
2

Я довольно новичок в OpenCV и C/C++ (был кодирован в Java и C# хотя). Я работаю над проектом (скорее роботом), который обнаруживает светофоры и знаки (только знак остановки). Теперь я нашел отличный учебник и использовал код, указанный в учебнике, так как он предназначен для обнаружения объектов красного цвета. Поскольку он настраивается, я могу настроить его на то, чтобы свет трафика был просто прекрасным.Обнаружение присутствия объекта в изображении

Ссылка на tutorial- 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 документацию и другие возможные вопросы по StackOverflow, но ни один, что я нашел обратитесь к моей проблеме. Поверьте мне, я спрашиваю об этом после довольно много спотыкания здесь и там в моих поисках ответов.

Так что мои вопросы are-

Q1. Так как я новичок в C/C++ (код учебника написан на C++), какие возможные способы могут сигнализировать, когда свет включен или нет? Мне по крайней мере нужно показать на экране, что свет погас, и когда он вернулся. Я попытался несколько способов, но никто не работал. (Не имеет значения, нужно ли преобразовать изображение в оттенки серого) (Пример - остановка msg отображается на экране, когда свет включен и выключается)

Q2. Как определить признаки и предпринять соответствующие действия. Здесь обнаружение не является большой проблемой (много доступных учебных пособий, я могу справиться с этим, но любые советы будут оценены), принимая меры к обнаружению.

Q3. Это может быть вне темы, но имеет решающее значение для моего проекта. В настоящее время я разрабатываю код на своем ПК с ОС Windows, но я намерен использовать его на Raspberry Pi 3, который, в свою очередь, будет управлять ведомой консолью Arduino UNO, которая контролирует двигатели. Из всех моих исследований до сих пор я узнал, что OpenCV на RPi используется в python, тогда как я кодирую в C/C++. Так что я могу запустить свой код, как он был написан на моем ПК на RPi, или мне нужно сначала переписать его на python, а затем поместить его на Pi. (И, о, если вы можете дать мне дальнейшие идеи о том, как идти дальше с остальной частью моего проекта это будет здорово!)

Я, очевидно, не прошу вас всех научить меня C++. Но несколько ключевых слов или пример кода были бы замечательными. И имейте в виду, что, поскольку окончательное использование этого кода будет на интерфейсе RPi с Arduino, если вы сможете сохранить код в этом контексте, было бы лучше. В противном случае просто ответьте в ответ на Windows, я буду модифицировать код так или иначе и заставить его работать на RPi. Я полностью программист на самообучении, и мне всего 17 лет, поэтому я тоже немного сторонник аутсорсинга, но помощи от таких людей, как вы, более чем достаточно, чтобы я работал.

Спасибо.

+0

Я думаю, что, зная, что вы используете C++, а не C может быть хорошей отправной точкой – Miki

+0

Моя плохая @Miki Я отредактировал мой вопрос. Как я уже сказал, я мало знаю об этих двух языках ... В любом случае спасибо. Итак, теперь, когда у меня есть хорошая отправная точка, куда идти дальше? –

+0

Вы можете задать один вопрос на вопрос ... И идти шаг за шагом ...; D. Что касается Q1, вы можете показать некоторые примеры включения/выключения светофоров ... Если у вас есть код для проверки на включение/выключение (не этот код учебника, который в принципе бесполезен здесь), мы можем начать с этого. – Miki

ответ

-1

Здесь есть много вопросов. Вероятно, вам лучше использовать обработку или python, потому что вам нужно использовать ее на малине pi, которая является linux. Любые файлы заголовков или библиотеки, которые вы используете, основанные на Windows, не будут работать в Linux, и если ваша работа с Ubuntu, создающая opencv в linux, может быть настоящей болью. Обработка является кросс-платформой и имеет библиотеки opencv, которые запускаются, а также рассматриваются как расширение кода arduino, поскольку синтаксис очень схож. Здесь я начну.

, как для красного света здесь несколько простых шагов

выбери регион «повышает интерес рои» для остановки знака в центре камеры квадрата, что составляет около 25-50 процентов в центре кадр, затем выполните поиск через пиксель пикселя по пикселям для красного цвета. если x процентов от красного цвета красного цвета, перед камерой стоит знак остановки.

да downvote парень с рабочим кодом

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; 
} 

после определения цвета вы сравнить его с рои, если достаточно вашего рои обнаружил цвет, то есть знак остановки! создайте значение bool для просмотра знака остановки и когда это будет истинным процессом остальной части вашего кода.

+0

Хммм может работать OpenCV на Кали? Это единственный Linux, который у меня есть сейчас. Любые советы о том, как выбрать roi? И я предполагаю, что фрагмент кода будет внутри цикла, верно? –

+1

См. Мои объяснения, которые теперь выше моего другого ответа. Оба этих примера кода работают и являются частью библиотеки примеров opencv_processing. обработка может экспортироваться как java или exe прямо в linux, поэтому вы должны быть достаточно знакомы, чтобы работать с ней, и есть учебные пособия для использования библиотеки обработки raw в java. Не говоря уже о том, что вы можете легко импортировать последовательный ввод/вывод для управления spi для arduino посредством обработки с использованием того же синтаксиса. Я уже делал такие проекты, как ваш, в гораздо более масштабном масштабе, используя обработку и arduino, этот материал прост в использовании, и он просто работает. –

0

пример пояснение roi использование opencv обработка библиотека. Вы просто загружаете обработку 2.0 или более поздней версии и импортируете библиотеку с помощью простого инструмента opencv для обработки. Я не собираюсь делать для вас весь ваш проект. Создайте статическую роу в центре кадра, и если в цвете обнаружен цвет, у вас есть знак остановки перед вами, чтобы увидеть рабочий код ниже, чтобы определить пороговые цвета.

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(); 
    } 
} 
+0

Спасибо за тонну! –