[Robotvision-commit] SF.net SVN: robotvision:[26] vision
Brought to you by:
phildavidson
From: <phi...@us...> - 2010-06-07 23:12:31
|
Revision: 26 http://robotvision.svn.sourceforge.net/robotvision/?rev=26&view=rev Author: phildavidson Date: 2010-06-07 23:12:24 +0000 (Mon, 07 Jun 2010) Log Message: ----------- Modified Paths: -------------- vision/src/ellipse.cpp Added Paths: ----------- vision/images/pipeEllipse.png vision/images/pipeSquareSideBySide.png vision/images/testFlipper.png vision/src/test5.cpp vision/src/test6.cpp Added: vision/images/pipeEllipse.png =================================================================== (Binary files differ) Property changes on: vision/images/pipeEllipse.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: vision/images/pipeSquareSideBySide.png =================================================================== (Binary files differ) Property changes on: vision/images/pipeSquareSideBySide.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: vision/images/testFlipper.png =================================================================== (Binary files differ) Property changes on: vision/images/testFlipper.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: vision/src/ellipse.cpp =================================================================== --- vision/src/ellipse.cpp 2010-06-06 19:11:40 UTC (rev 25) +++ vision/src/ellipse.cpp 2010-06-07 23:12:24 UTC (rev 26) @@ -186,7 +186,7 @@ return retElipse; } -int zmain(int argc, char** argv) { +int tmain(int argc, char** argv) { cvNamedWindow("original", CV_WINDOW_AUTOSIZE); Copied: vision/src/test5.cpp (from rev 14, vision/src/test.cpp) =================================================================== --- vision/src/test5.cpp (rev 0) +++ vision/src/test5.cpp 2010-06-07 23:12:24 UTC (rev 26) @@ -0,0 +1,330 @@ +#include "iostream" +#include "stdlib.h" +#include "stdio.h" +#include "cv.h" +#include "highgui.h" +#include "cstring" + +/*the includes*/ +/*This program is not done in CVBlob library*/ +/*Purpose of the program to track the blob */ +using namespace std; + +/*Note:The detection algorithm is the same as the one you can find in one of my previous posts + + The same algorithm is copied from that post and pasted in this + post only the values of the "sthreshold" and the "hupper" and the "hlower" are different....*/ + +double anglet(CvPoint* pt1, CvPoint* pt2, CvPoint* pt0) { + double dx1 = pt1->x - pt0->x; + double dy1 = pt1->y - pt0->y; + double dx2 = pt2->x - pt0->x; + double dy2 = pt2->y - pt0->y; + return (dx1 * dx2 + dy1 * dy2) / sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + + dy2 * dy2) + 1e-10); +} + +// returns sequence of squares detected on the image. +// the sequence is stored in the specified memory storage +CvSeq* findSquares4t(IplImage* img) { + int thresh = 50; + CvSeq* contours; + int i, c, l, N = 11; + CvSize sz = cvSize(img->width & -2, img->height & -2); + IplImage* timg = cvCloneImage(img); // make a copy of input image + IplImage* gray = cvCreateImage(sz, 8, 1); + IplImage* pyr = cvCreateImage(cvSize(sz.width / 2, sz.height / 2), 8, 3); + IplImage* tgray; + CvSeq* result; + double s, t; + + CvMemStorage* storage = 0; + + storage = cvCreateMemStorage(0); + + // create empty sequence that will contain points - + // 4 points per square (the square's vertices) + CvSeq* squares = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), storage); + + // select the maximum ROI in the image + // with the width and height divisible by 2 + cvSetImageROI(timg, cvRect(0, 0, sz.width, sz.height)); + + // down-scale and upscale the image to filter out the noise + cvPyrDown(timg, pyr, 7); + cvPyrUp(pyr, timg, 7); + tgray = cvCreateImage(sz, 8, 1); + + // find squares in every color plane of the image + for (c = 0; c < 3; c++) { + // extract the c-th color plane + cvSetImageCOI(timg, c + 1); + cvCopy(timg, tgray, 0); + + // try several threshold levels + for (l = 0; l < N; l++) { + // hack: use Canny instead of zero threshold level. + // Canny helps to catch squares with gradient shading + if (l == 0) { + // apply Canny. Take the upper threshold from slider + // and set the lower to 0 (which forces edges merging) + cvCanny(tgray, gray, 0, thresh, 5); + // dilate canny output to remove potential + // holes between edge segments + cvDilate(gray, gray, 0, 1); + } else { + // apply threshold if l!=0: + // tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 + cvThreshold(tgray, gray, (l + 1) * 255 / N, 255, + CV_THRESH_BINARY ); + } + + // find contours and store them all as a list + cvFindContours(gray, storage, &contours, sizeof(CvContour), + CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0)); + + // test each contour + while (contours) { + // approximate contour with accuracy proportional + // to the contour perimeter + result = cvApproxPoly(contours, sizeof(CvContour), storage, + CV_POLY_APPROX_DP, cvContourPerimeter(contours) * 0.02, + 0); + // square contours should have 4 vertices after approximation + // relatively large area (to filter out noisy contours) + // and be convex. + // Note: absolute value of an area is used because + // area may be positive or negative - in accordance with the + // contour orientation + if (result->total == 4 + && cvContourArea(result, CV_WHOLE_SEQ, 0) > 1000 + && cvCheckContourConvexity(result)) { + s = 0; + + for (i = 0; i < 5; i++) { + // find minimum angle between joint + // edges (maximum of cosine) + if (i >= 2) { + t = fabs(anglet((CvPoint*) cvGetSeqElem(result, i), + (CvPoint*) cvGetSeqElem(result, i - 2), + (CvPoint*) cvGetSeqElem(result, i - 1))); + s = s > t ? s : t; + } + } + + // if cosines of all angles are small + // (all angles are ~90 degree) then write quandrange + // vertices to resultant sequence + if (s < 0.3) + for (i = 0; i < 4; i++) + cvSeqPush(squares, (CvPoint*) cvGetSeqElem(result, + i)); + } + + // take the next contour + contours = contours->h_next; + } + } + } + + // release all the temporary images + cvReleaseImage(&gray); + cvReleaseImage(&pyr); + cvReleaseImage(&tgray); + cvReleaseImage(&timg); + cvClearMemStorage(storage); + return squares; +} + +// the function draws all the squares in the image +void drawSquarest(IplImage* img, CvSeq* squares) { + CvSeqReader reader; + //IplImage* cpy = cvCloneImage( img ); + int i; + + // initialize reader of the sequence + cvStartReadSeq(squares, &reader, 0); + + // read 4 sequence elements at a time (all vertices of a square) + for (i = 0; i < squares->total; i += 4) { + CvPoint pt[4], *rect = pt; + int count = 4; + + // read 4 vertices + CV_READ_SEQ_ELEM( pt[0], reader ); + CV_READ_SEQ_ELEM( pt[1], reader ); + CV_READ_SEQ_ELEM( pt[2], reader ); + CV_READ_SEQ_ELEM( pt[3], reader ); + + // draw the square as a closed polyline + cvPolyLine(img, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0); + } + + // show the resultant image + //cvReleaseImage( &cpy ); +} + +int zmain(int argc, char** argv) + +{ + int sthreshold = 86, erode = 4, dialate = 8; + + int hlower = 127, hupper = 18; + + cvNamedWindow("original", CV_WINDOW_AUTOSIZE); + + cvNamedWindow("processed", CV_WINDOW_AUTOSIZE); + + //cvCreateTrackbar("sthreshold", "Monochrome Of red Blob", &sthreshold, 255, 0); + //cvCreateTrackbar("hlower", "Monochrome Of red Blob", &hlower, 255, 0); + //cvCreateTrackbar("hupper", "Monochrome Of red Blob", &hupper, 255, 0); + //cvCreateTrackbar("erode", "Monochrome Of red Blob", &erode, 20, 0); + //cvCreateTrackbar("dialate", "Monochrome Of red Blob", &dialate, 20, 0); + + int i, j, k;//for iterations + int temp = 0;//if we use a temporary var + int delay=100; + + cvCreateTrackbar("delay", "original", &delay, 150, 0); + + int heighthsv, widthhsv, stephsv, channelshsv; + int heightmono, widthmono, stepmono, channelsmono; + uchar *datahsv, *datamono; + + IplImage *frame; + IplImage *colimgbot; + + IplImage *monoimgbot; + + CvCapture* capture = cvCreateFileCapture("videos/pipe3.avi"); + //CvCapture* capture = cvCreateFileCapture("videos/ets2007pipe.avi"); + + + if (!capture) { + + printf("Cannot open video file!\n"); + + return (1); + + } + + + + for (;;) { + + if (!cvGrabFrame(capture)) { + + break; + + } + + frame = cvRetrieveFrame(capture); + + if (frame == NULL) { + puts("unable to load the frame"); + exit(0); + } + //printf("frame loaded"); + + colimgbot = cvCreateImage(cvGetSize(frame), 8, 3); + + monoimgbot = cvCreateImage(cvGetSize(frame), 8, 1); + + cvCvtColor(frame, colimgbot, CV_RGB2HSV); + + //\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97 + + heighthsv = colimgbot->height; + widthhsv = colimgbot->width; + stephsv = colimgbot->widthStep; + channelshsv = colimgbot->nChannels; + datahsv = (uchar *) colimgbot->imageData; + //\x97\x97\x97\x97\x97\x97\x97\x97\x96 + + heightmono = monoimgbot ->height; + widthmono = monoimgbot->width; + stepmono = monoimgbot->widthStep; + channelsmono = monoimgbot->nChannels; + datamono = (uchar *) monoimgbot->imageData; + + for (i = 0; i < (heighthsv); i++) { + for (j = 0; j < (widthhsv); j++) { + if ((datahsv[(i) * stephsv + j * channelshsv] <= hlower) + && (datahsv[(i) * stephsv + j * channelshsv] >= hupper)) { + if ((datahsv[(i) * stephsv + j * (channelshsv) + 1]) + > sthreshold) { + datamono[i * stepmono + j * channelsmono] = 255; + } else + datamono[i * stepmono + j * channelsmono] = 0; + } + } + } + + for (i = 0; i < (heighthsv); i++) { + for (j = 0; j < (widthhsv); j++) { + if (!(datamono[i * stepmono + j * channelsmono] == 0 + || datamono[i * stepmono + j * channelsmono] == 255)) + datamono[i * stepmono + j * channelsmono] = 0; + } + } + + cvErode(monoimgbot, monoimgbot, 0, erode); + cvDilate(monoimgbot, monoimgbot, 0, dialate); + + int w = 0; + int countw = 0; + int h = 0; + int counth = 0; + + for (i = 0; i < (heighthsv); i++) { + for (j = 0; j < (widthhsv); j++) { + if (datamono[i * stepmono + j * channelsmono] == 255) { + + w += j; + countw++; + h += i; + counth++; + } + } + } + + cvSaveImage("testimg.png", monoimgbot); + //cvCvtColor(monoimgbot, img2, CV_GRAY2RGB); + + + IplImage * img2 = cvLoadImage("testimg.png", 1); + + drawSquarest(img2, findSquares4t(img2)); + + if (countw != 0 && counth != 0) { + w = w / countw; + h = h / counth; + + cvCircle(frame, cvPoint(w, h), 20, cvScalar(0, 255, 0), 1); + + cvCircle(img2, cvPoint(w, h), 20, cvScalar(0, 255, 0), 1); + + } + + + cvShowImage("original", frame); + //cvSaveImage("red-ballmonochrome.jpg",monoimgbot);/*if you want to save the image*/ + cvShowImage("processed", img2); + int c = cvWaitKey(delay); + if ((char) c == 27) + break; + + } + + /* free memory */ + + //cvReleaseVideoWriter(&writer); + + cvDestroyWindow("processed"); + cvDestroyWindow("original"); + + cvReleaseCapture(&capture); + + exit(0); +} + Copied: vision/src/test6.cpp (from rev 14, vision/src/test2.cpp) =================================================================== --- vision/src/test6.cpp (rev 0) +++ vision/src/test6.cpp 2010-06-07 23:12:24 UTC (rev 26) @@ -0,0 +1,134 @@ +/*ALL the necessary header files*/ + +#include"math.h" +#include"conio.h" +#include"cv.h" +#include"highgui.h" +#include"stdio.h" +int bmain() { + + int sthreshold = 68, erode = 6, dialate = 10; + + int hlower = 127, hupper = 5;/* + here hlower is the lower cut off and the hupper is the upper cut off for hue values of red.*/ + + cvNamedWindow("original", CV_WINDOW_AUTOSIZE); + + cvNamedWindow("processed", CV_WINDOW_AUTOSIZE); + + cvCreateTrackbar("sthreshold", "processed", &sthreshold, 255, + 0); + cvCreateTrackbar("hlower", "processed", &hlower, 255, 0); + cvCreateTrackbar("hupper", "processed", &hupper, 255, 0); + cvCreateTrackbar("erode", "processed", &erode, 20, 0); + cvCreateTrackbar("dialate", "processed", &dialate, 20, 0); + + int i, j, k;//for iterations + int temp = 0;//if we use a temporary var + /*here lets look at the word \x93heighthsv\x94 \x85now lets breadk up this word\x85here height means + + height as a regular IplImage Structure has now the addition \x93hsv\x94 to the word heigh means this + height attribute is for the image which is color converted to the hsv,Similar conventions + for the monochrome image\x85so you may find the attribute height for the monochrome image to be + heightmono\x85So i believe it is easy\x85*/ + int heighthsv, widthhsv, stephsv, channelshsv; + int heightmono, widthmono, stepmono, channelsmono; + uchar *datahsv, *datamono; + + IplImage *frame; + IplImage *colimgbot; + + IplImage *monoimgbot; + + for (;;) { + + + + + i = j = k = 0;/*initializing the iteraiton variables to be zero*/ + + + //frame = cvLoadImage("images/3dballs.jpg", 1); + frame=cvLoadImage("images/flipper.png",1); + + if (frame == NULL) { + puts("unable to load the frame"); + exit(0); + } + //printf("frame loaded"); + colimgbot = cvCreateImage(cvGetSize(frame), 8, 3); + + monoimgbot = cvCreateImage(cvGetSize(frame), 8, 1); + + cvCvtColor(frame, colimgbot, CV_RGB2HSV); + + //\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97\x97 + + heighthsv = colimgbot->height; + widthhsv = colimgbot->width; + stephsv = colimgbot->widthStep; + channelshsv = colimgbot->nChannels; + datahsv = (uchar *) colimgbot->imageData; + //\x97\x97\x97\x97\x97\x97\x97\x97\x96 + + heightmono = monoimgbot ->height; + widthmono = monoimgbot->width; + stepmono = monoimgbot->widthStep; + channelsmono = monoimgbot->nChannels; + datamono = (uchar *) monoimgbot->imageData; + + for (i = 0; i < (heighthsv); i++) { + for (j = 0; j < (widthhsv); j++) { + if ((datahsv[(i) * stephsv + j * channelshsv] <= hlower) + && (datahsv[(i) * stephsv + j * channelshsv] >= hupper)) { + if ((datahsv[(i) * stephsv + j * (channelshsv) + 1]) + > sthreshold) { + datamono[i * stepmono + j * channelsmono] = 255; + } else + /*A very simple concept with the loops here if the hue values are in the aforementioned range and the + threshold is met then logic one else logic zero*/ + datamono[i * stepmono + j * channelsmono] = 0; + } + } + } + + for (i = 0; i < (heighthsv); i++) { + for (j = 0; j < (widthhsv); j++) { + if (!(datamono[i * stepmono + j * channelsmono] == 0 + || datamono[i * stepmono + j * channelsmono] == 255)) + datamono[i * stepmono + j * channelsmono] = 0; + } + }/*Just a cross chek to ensure whether all the pixels have only + either 0 or 255*/ + /*Please check these links for the explanation of the erosion and dilation functions + + http://www.dca.fee.unicamp.br/dipcourse/html-dip/c9/s4/front-page.html*/ + + /*so now the last parameter in the function indicates how many times you want to apply dilation + + or erosion*/ + + cvErode(monoimgbot, monoimgbot, 0, erode); + cvDilate(monoimgbot, monoimgbot, 0, dialate); + /*here i have experimented with the values by changing them\x85and i have found + that i come to a good result by applying erosion 6 times and dilation 15 times + you can comment/uncomment play with the values and see what is going on + Sometimes you will find the areas which are shining in the image also get detected\x85 + + Please think why and then try to post a comment the best commment would get visible on this page*/ + + cvShowImage("original", frame); + //cvSaveImage("red-ballmonochrome.jpg",monoimgbot);/*if you want to save the image*/ + cvShowImage("processed", monoimgbot); + int c = cvWaitKey(0); + if ((char) c == 27) + break; + /*for all the other clarifications you can check the other posts\x85. you will find an answer + People who are getting started with the Opencv must make sure you + + check the other posts on this blog*/ + } + cvDestroyWindow("processed"); + cvDestroyWindow("original"); + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |