Перейти к содержимому
Compvision.ru
kames

OpenCV поиск синего шарика

Recommended Posts

Имеется код программы взят http://blog.vidikon.com/?p=479

#include <opencv2/video/tracking.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

using namespace cv;

using namespace std;

void FindBall(IplImage* Img);

void Counter(IplImage* img);

CvPoint2D32f center;

float radius;

long pointer=0;

int main( int argc, char** argv )

{

 CvCapture *capture = cvCreateCameraCapture(CV_CAP_ANY);

 cvNamedWindow( "Demo", 1 );

for(;

{

IplImage* frame = 0;

int c;

frame = cvQueryFrame( capture );

if( !frame )

break;

FindBall(frame);

cvShowImage( "Demo", frame );

c = cvWaitKey(50);

if( (char)c == 27 )

break;

pointer++;

}

cvWaitKey(0);

cvReleaseCapture( &capture );

cvDestroyWindow("Demo");

return 0;

}





void FindBall(IplImage* Img)

{

IplImage* Image=cvCreateImage( cvGetSize(Img), 8, 3 );

cvCopy(Img,Image);

uchar* ptr1;

ptr1 = (uchar*) (Image->imageData );

int i,j;

for(i=0;i<Img->height;i++)

for(j=0;j<Img->width;j++)

{

if (ptr1[j*3+i*Image->widthStep]>3*ptr1[j*3+1+i*Image->widthStep] &&

ptr1[j*3+i*Image->widthStep]>3*ptr1[j*3+2+i*Image->widthStep])

{

ptr1[j*3+i*Image->widthStep]=255;

ptr1[j*3+1+i*Image->widthStep]=255;

ptr1[j*3+2+i*Image->widthStep]=255;

}

else

{

ptr1[j*3+i*Image->widthStep]=0;

ptr1[j*3+1+i*Image->widthStep]=0;

ptr1[j*3+2+i*Image->widthStep]=0;

}

}

Counter(Image);

if (center.x>-1)

{

CvPoint p;

p.x=center.x;

p.y=center.y;

cvCircle( Img, p, radius, CV_RGB(255,0,0), 3, 8, 0 );

}

cvReleaseImage( &Image );

}





void Counter(IplImage* img)

{

IplImage* img_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1);

CvSeq* contours = 0;

CvMemStorage* storage = cvCreateMemStorage(0);

cvCvtColor( img, img_gray, CV_BGR2GRAY );

cvFindContours( img_gray, storage, &contours, sizeof(CvContour),

CV_RETR_LIST  , CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

CvSeq* h_next=0;

for( CvSeq* c=contours; c!=NULL; c=c->h_next )

{

if (c!=contours)

{

if (h_next->total>=c->total)

{

h_next->h_next=h_next->h_next->h_next;

continue;

}

}

h_next=c;

}

center.x=-1;

if (h_next->total<200) return;

cvDrawContours( img, h_next, CV_RGB(255,0,0), CV_RGB(0,255,0),2, 2, CV_AA, cvPoint(0,0) );

cvMinEnclosingCircle(h_next,&center,&radius);

cvReleaseMemStorage( &storage);

cvReleaseImage( &img_gray );

}



Так вот тут я поменял коофиценты чтобы он искал синий шарик но к сожалению он не только шарик определяет но и синий колпачок если его поднести достаточно близко


 вот код другой программы взят с http://robocraft.ru/blog/computervision/640.html и немного переделанный мной

#include <opencv2/video/tracking.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <iostream>

using namespace cv;

using namespace std;

void findCircles(IplImage* _image)

{

        assert(_image!=0);


        IplImage* bin = cvCreateImage( cvGetSize(_image), IPL_DEPTH_8U, 1);

        cvConvertImage(_image, bin, CV_BGR2GRAY);


        cvCanny(bin, bin, 50, 200);

        CvMemStorage* storage = cvCreateMemStorage(0);

        CvSeq* contours=0;



        int contoursCont = cvFindContours( bin, storage,&contours,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));

        contours = cvApproxPoly( contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );


        assert(contours!=0);



        for( CvSeq* current = contours; current != NULL; current = current->h_next ){

                        // вычисляем площадь и периметр контура

                        double area = fabs(cvContourArea(current));

                        double perim = cvContourPerimeter(current);


                        // 1/4*CV_PI = 0,079577

                        if ( area / (perim * perim) > 0.07 && area / (perim * perim)< 0.9 ){ // в 10% интервале

                                // нарисуем контур

                                cvDrawContours(_image, current, cvScalar(0, 0, 255), cvScalar(0, 255, 0), -1, 4, 8);

                        }

                }



        cvReleaseMemStorage(&storage);

        cvReleaseImage(&bin);

}


int main(int argc, char* argv[])

{

        cvNamedWindow("capture");

        cvNamedWindow("image");

        CvCapture *capture = cvCreateCameraCapture(CV_CAP_ANY);

        assert(capture!=0);

 IplImage* frame = 0;

 //IplImage* dst = 0;

 //CvSeq* contours = 0;

        while(true){

               frame = cvQueryFrame( capture );

               cvShowImage("capture", frame);

               // dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 3 );

               findCircles(frame);

                cvShowImage("image", frame);

               // cvShowImage("ima", dts);

                char c = cvWaitKey(1);

                if (c == 27) {

                        break;

                }

        }



        cvReleaseCapture( &capture );

      //  cvReleaseImage(&dst);

        cvDestroyAllWindows();

}[/code]

но он к сожалению тоже не корректно работает он определяет только в идеале т.е нарисованный на бумаге круг а шарик не видит в каком направление мне двигаться?как их объединить чтобы найти синий шарик?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Эту программу можно научить искать любой объект по цвету

http://www.compvision.ru/forum/index.php?showtopic=861

Плюс надо выделить контуры (cvCanny), и найти окружности (cvHoughCircles).

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Столкнулся c такой проблемой cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); не распознаётся я собирал opencv с помощью CMake (cmake-gui) и вот он не создал cv.h cv.hpp подскажите что делать может есть какая-то альтернативная библиотека

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот эти заголовки включите (на все случаи жизни):

#include "opencv2/core/core.hpp"
#include "opencv2/core/gpumat.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
[/code]

А вообще-то есть поиск по тексту. Набираете функцию, которую хотите найти и ищете её в заголовочных файлах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот эти заголовки включите (на все случаи жизни):

#include "opencv2/core/core.hpp"

#include "opencv2/core/gpumat.hpp"

#include "opencv2/core/opengl_interop.hpp"

#include "opencv2/gpu/gpu.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/contrib/contrib.hpp"

#include "opencv2/video/tracking.hpp"

#include "opencv2/imgproc/imgproc.hpp"

А вообще-то есть поиск по тексту. Набираете функцию, которую хотите найти и ищете её в заголовочных файлах.

не помогло =(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А, забыл еще

#include "opencv2/legacy/legacy.hpp"

там содержатся всякие древние функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А, забыл еще

#include "opencv2/legacy/legacy.hpp"
там содержатся всякие древние функции.
Всё равно вот код
#include "opencv2/core/core.hpp"

#include "opencv2/core/mat.hpp"

#include "opencv2/gpu/gpu.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/contrib/contrib.hpp"

#include "opencv2/video/tracking.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/legacy/legacy.hpp"

#include <iostream>

#include <stdlib.h>

#include <stdio.h>


IplImage* image = 0;

IplImage* dst = 0;


// для хранения каналов HSV

IplImage* hsv = 0;

IplImage* h_plane = 0;

IplImage* s_plane = 0;

IplImage* v_plane = 0;

// для хранения каналов HSV после преобразования

IplImage* h_range = 0;

IplImage* s_range = 0;

IplImage* v_range = 0;

// для хранения суммарной картинки

IplImage* hsv_and = 0;


int Hmin = 0;

int Hmax = 256;


int Smin = 0;

int Smax = 256;


int Vmin = 0;

int Vmax = 256;


int HSVmax = 256;


//

// функции-обработчики ползунков

//

void myTrackbarHmin(int pos) {

        Hmin = pos;

        cvInRangeS(h_plane, cvScalar(Hmin), cvScalar(Hmax), h_range);

}


void myTrackbarHmax(int pos) {

        Hmax = pos;

        cvInRangeS(h_plane, cvScalar(Hmin), cvScalar(Hmax), h_range);

}


void myTrackbarSmin(int pos) {

        Smin = pos;

        cvInRangeS(s_plane, cvScalar(Smin), cvScalar(Smax), s_range);

}


void myTrackbarSmax(int pos) {

        Smax = pos;

        cvInRangeS(s_plane, cvScalar(Smin), cvScalar(Smax), s_range);

}


void myTrackbarVmin(int pos) {

        Vmin = pos;

        cvInRangeS(v_plane, cvScalar(Vmin), cvScalar(Vmax), v_range);

}


void myTrackbarVmax(int pos) {

        Vmax = pos;

        cvInRangeS(v_plane, cvScalar(Vmin), cvScalar(Vmax), v_range);

}


int main(int argc, char* argv[])

{

        // имя картинки задаётся первым параметром

        char* filename ="D:\Image0.jpg";

        // получаем картинку

        image = cvLoadImage(filename,1);


        printf("[i] image: %s\n", filename);

        assert( image != 0 );


        // создаём картинки

        hsv = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 3 );

        h_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        s_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        v_plane = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        h_range = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        s_range = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        v_range = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        hsv_and = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1 );

        //  конвертируем в HSV

        cvCvtColor( image, hsv, CV_BGR2HSV );

        // разбиваем на отельные каналы

        cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );


        //

        // определяем минимальное и максимальное значение

        // у каналов HSV

        double framemin=0;

        double framemax=0;


        cvMinMaxLoc(h_plane, &framemin, &framemax);

        printf("[H] %f x %f\n", framemin, framemax );

        Hmin = framemin;

        Hmax = framemax;

        cvMinMaxLoc(s_plane, &framemin, &framemax);

        printf("[S] %f x %f\n", framemin, framemax );

        Smin = framemin;

        Smax = framemax;

        cvMinMaxLoc(v_plane, &framemin, &framemax);

        printf("[V] %f x %f\n", framemin, framemax );

        Vmin = framemin;

        Vmax = framemax;


        // окна для отображения картинки

        cvNamedWindow("original",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("H",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("S",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("V",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("H range",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("S range",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("V range",CV_WINDOW_AUTOSIZE);

        cvNamedWindow("hsv and",CV_WINDOW_AUTOSIZE);


        cvCreateTrackbar("Hmin", "H range", &Hmin, HSVmax, myTrackbarHmin);

        cvCreateTrackbar("Hmax", "H range", &Hmax, HSVmax, myTrackbarHmax);

        cvCreateTrackbar("Smin", "S range", &Smin, HSVmax, myTrackbarSmin);

        cvCreateTrackbar("Smax", "S range", &Smax, HSVmax, myTrackbarSmax);

        cvCreateTrackbar("Vmin", "V range", &Vmin, HSVmax, myTrackbarVmin);

        cvCreateTrackbar("Vmax", "V range", &Vmax, HSVmax, myTrackbarVmax);


        //

        // разместим окна по рабочему столу

        //

        if(image->width <1920/4 && image->height<1080/2){

                cvMoveWindow("original", 0, 0);

                cvMoveWindow("H", image->width+10, 0);

                cvMoveWindow("S", (image->width+10)*2, 0);

                cvMoveWindow("V", (image->width+10)*3, 0);

                cvMoveWindow("hsv and", 0, image->height+30);

                cvMoveWindow("H range", image->width+10, image->height+30);

                cvMoveWindow("S range", (image->width+10)*2, image->height+30);

                cvMoveWindow("V range", (image->width+10)*3, image->height+30);

        }


        while(true){


                // показываем картинку

                cvShowImage("original",image);


                cvShowImage( "H", h_plane );

                cvShowImage( "S", s_plane );

                cvShowImage( "V", v_plane );


                cvShowImage( "H range", h_range );

                cvShowImage( "S range", s_range );

                cvShowImage( "V range", v_range );


                // складываем

                cvAnd(h_range, s_range, hsv_and);

                cvAnd(hsv_and, v_range, hsv_and);


                cvShowImage( "hsv and", hsv_and );


                char c = cvWaitKey(33);

                if (c == 27) { // если нажата ESC - выходим

                        break;

                }

        }

        printf("\n[i] Results:\n" );

        printf("[H] %d x %d\n", Hmin, Hmax );

        printf("[S] %d x %d\n", Smin, Smax );

        printf("[V] %d x %d\n", Vmin, Vmax );


        // освобождаем ресурсы

        cvReleaseImage(&image);

        cvReleaseImage(&hsv);

        cvReleaseImage(&h_plane);

        cvReleaseImage(&s_plane);

        cvReleaseImage(&v_plane);

        cvReleaseImage(&h_range);

        cvReleaseImage(&s_range);

        cvReleaseImage(&v_range);

        cvReleaseImage(&hsv_and);

        // удаляем окна

        cvDestroyAllWindows();

        return 0;

}

не помогает =(

post-5549-0-49601000-1337717850_thumb.jp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

#include "opencv2/legacy/compat.hpp"

добавил и у меня все скомпилировалось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

#include "opencv2/legacy/compat.hpp"
добавил и у меня все скомпилировалось.
вот код программы столкнулся с той же проблемой подношу синий шарик видет его всё ок потом подношу синиколпачок от фломастера он и его распознаёт как круг

#include "opencv2/core/core.hpp"

#include "opencv2/core/mat.hpp"

#include "opencv2/gpu/gpu.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/contrib/contrib.hpp"

#include "opencv2/video/tracking.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/legacy/legacy.hpp"

#include "opencv2/legacy/compat.hpp"

#include <iostream>

#include <stdlib.h>

#include <stdio.h>


int main(int argc, char* argv[])

{



        CvSize size = cvSize(640,480);

        CvCapture* capture = cvCaptureFromCAM( 0 );

        if( !capture )

        {


                getchar();

                return -1;

        }

        cvNamedWindow( "Camera", CV_WINDOW_AUTOSIZE );

        cvNamedWindow( "HSV", CV_WINDOW_AUTOSIZE );

        cvNamedWindow( "EdgeDetection", CV_WINDOW_AUTOSIZE );

        CvScalar hsv_min = cvScalar(107, 156, 52, 0);

        CvScalar hsv_max = cvScalar(256, 256, 255, 0);

        IplImage *  hsv_frame    = cvCreateImage(size, IPL_DEPTH_8U, 3);

        IplImage*  thresholded   = cvCreateImage(size, IPL_DEPTH_8U, 1);

        while( true )

        {


            IplImage* frame = cvQueryFrame( capture );

            if( !frame )

            {


                    getchar();

                    break;

            }


            cvCvtColor(frame, hsv_frame, CV_BGR2HSV);

            cvInRangeS(hsv_frame, hsv_min, hsv_max, thresholded);

            CvMemStorage* storage = cvCreateMemStorage(0);

            cvSmooth( thresholded, thresholded, CV_GAUSSIAN, 9, 9 );

            CvSeq* circles = cvHoughCircles(thresholded, storage, CV_HOUGH_GRADIENT, 2,

                                            thresholded->height/4, 100, 50, 10, 400);

           for (int i = 0; i < circles->total; i++)

            {

                float* p = (float*)cvGetSeqElem( circles, i );


                cvCircle( frame, cvPoint(cvRound(p[0]),cvRound(p[1])),

                                        3, CV_RGB(0,255,0), -1, 8, 0 );

                cvCircle( frame, cvPoint(cvRound(p[0]),cvRound(p[1])),

                                        cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );

            }

           cvShowImage( "Camera", frame );

           cvShowImage( "HSV", hsv_frame);

           cvShowImage( "After Color Filtering", thresholded );

            cvReleaseMemStorage(&storage);


            if( (cvWaitKey(10)&255) == 27 ) break;

        }


         cvReleaseCapture( &capture );

         cvDestroyWindow( "mywindow" );

         return 0;

       }

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Возникла некая проблемка, компилирую вот этот код в vs C++ 2008

// Поиск.cpp: главный файл проекта.


#include "stdafx.h"

#include "cv.h"

#include "highgui.h"

#include <stdio.h>

#include <ctype.h>


void FindBall(IplImage* Img);

void Counter(IplImage* img);

CvPoint2D32f center;

float radius;

long pointer=0;



int main( int argc, char** argv )

{

CvCapture* capture = 0;

capture = cvCreateCameraCapture(CV_CAP_ANY);

cvNamedWindow( "Demo", 1 );

for(;

{

IplImage* frame = 0;

int i, k, c;

frame = cvQueryFrame( capture );

if( !frame )

break;

FindBall(frame);

cvShowImage( "Demo", frame );

c = cvWaitKey(50);

if( (char)c == 27 )

break;

pointer++;

}

cvWaitKey(0);

cvReleaseCapture( &capture );

cvDestroyWindow("Demo");

return 0;

}


void FindBall(IplImage* Img)

{

IplImage* Image=cvCreateImage( cvGetSize(Img), 8, 3 );

cvCopy(Img,Image);

//Теперь необходимо получить доступ к всем пикселям.

uchar* ptr1;

ptr1 = (uchar*) (Image->imageData );

int i,j;

for(i=0;i<Img->height;i++)

for(j=0;j<Img->width;j++)

{

//R > 1.5*G, R > 2*B

if (ptr1[j*3+2+i*Image->widthStep]>1.5*ptr1[j*3+1+i*Image->widthStep]

&&

ptr1[j*3+2+i*Image->widthStep]>2*ptr1[j*3+i*Image->widthStep])

{

ptr1[j*3+i*Image->widthStep]=255;

ptr1[j*3+1+i*Image->widthStep]=255;

ptr1[j*3+2+i*Image->widthStep]=255;

}

else

{

ptr1[j*3+i*Image->widthStep]=0;

ptr1[j*3+1+i*Image->widthStep]=0;

ptr1[j*3+2+i*Image->widthStep]=0;

}

}

//Выделение контуров и поиск наибольшего контура

Counter(Image);

if (center.x>-1)

{

CvPoint p;

p.x=center.x;

p.y=center.y;

cvCircle( Img, p, radius, CV_RGB(255,0,0), 3, 8, 0 );

}

cvReleaseImage( &Image );

}

void Counter(IplImage* img)

{

IplImage* img_gray= cvCreateImage( cvSize(img->width,img->height), 8, 1);

CvSeq* contours = 0;

CvMemStorage* storage = cvCreateMemStorage(0);

cvCvtColor( img, img_gray, CV_BGR2GRAY );

cvFindContours( img_gray, storage, &contours, sizeof(CvContour),

CV_RETR_LIST , CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

CvSeq* h_next=0;

//Поиск максимального контура

for( CvSeq* c=contours; c!=NULL; c=c->h_next )

{

if (c!=contours)

{

//Проверяем какой контур больше

if (h_next->total>=c->total)

{

h_next->h_next=h_next->h_next->h_next;

continue;

}

}

h_next=c;

}

center.x=-1;

if (h_next->total<200) return;//нет мяча - слишком маленькие контуры

cvDrawContours( img, h_next, CV_RGB(255,0,0), CV_RGB(0,255,0),2, 2, CV_AA,

cvPoint(0,0) );

//Минимальная окружность

cvMinEnclosingCircle(h_next,&center,&radius);

cvReleaseMemStorage( &storage);

cvReleaseImage( &img_gray );

}

[/code]

Код компилируется после создания окна вылезает окно, в нем написано "Дополнительные сведения: В экземпляре объекта не задана ссылка на объект."

и указывает с начало на эту строчку: if (h_next->total<200) return;//нет мяча - слишком маленькие контуры

потом, если её за коментить то указывает на вот эту строчку: cvMinEnclosingCircle(h_next,&center,&radius);

и выдает следующую надпись"Дополнительные сведения: Внешний компонент создал исключение"

В чем может быть проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ты приведи текст ошибки, который выдаётся в консоль (такое чёрненькое окошко, которое появляется при запуске твоей программы). Вот там и написано, в чём проблема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну так очевидно, что контур у тебя не нашёлся вовсе и h_next равен нулю. Сделай проверку на это.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×