How to detect specific number from image with OPENCV? - opencv

I live in Turkey, and in Turkey, TV commercials are making some countdowns which tells us how many minutes left to the tv program or film starts.
What I'am trying to do is catch the 00:59 seconds or just the 2nd "0" on the counter. The alghoritm must understand that the "0" is "0" not any other number.
After that I've tried template matching with template images but it detects wrong numbers too.
So I couldn't figured out which is the best way to do it...
I am trying to detect from these frames:
as you see it detects "1" instead of "0".
Below is my code with template matching;
#include<opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <sstream>
using namespace cv;
using namespace std;
Mat frame;
Mat img;
Mat templ;
Mat templ_resized;
Mat templ_resized_bw;
Mat result;
cv::Mat sel;
cv::Mat img_final;
//**************
int main(int argc, char** argv)
{
VideoCapture cap("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/kanaldkucukaga.avi");
if ( !cap.isOpened() )
{
cout << "Cannot open the video file" << endl;
return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
cout << "Frame per seconds : " << fps << endl;
namedWindow("1",CV_WINDOW_AUTOSIZE);
namedWindow("2",CV_WINDOW_AUTOSIZE);
namedWindow("3",CV_WINDOW_AUTOSIZE);
namedWindow("4",CV_WINDOW_AUTOSIZE);
namedWindow("5",CV_WINDOW_AUTOSIZE);
int counter=0;
int check_counter=0;
std::string s;
cv::Rect myROI(699, 474, 10,16); //location of the countdown Timer
cv::Mat cropped;
templ = imread("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/sifir00.png",CV_LOAD_IMAGE_COLOR);
cv::resize(templ,templ_resized,Size(8,11),CV_INTER_LINEAR); //8 11
Mat cropped_bw;
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
cv::Mat pic;
while(1)
{
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "Cannot read the frame from video file" << endl;
break;
}
counter=counter+1;
cv::Mat croppedRef(frame, myROI);
cvtColor(croppedRef,cropped_bw,CV_RGB2GRAY);
cropped_bw = cropped_bw > 200;
cvtColor(templ_resized,templ_resized_bw,CV_RGB2GRAY);
templ_resized_bw=templ_resized_bw>200;
imshow("1",cropped_bw);
imshow("2",frame);
imshow("3",templ);
imshow("4",templ_resized_bw);
int result_cols = cropped_bw.cols - templ_resized_bw.cols + 1;
int result_rows = cropped_bw.rows - templ_resized_bw.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
matchTemplate( cropped_bw,templ_resized_bw, result, CV_TM_SQDIFF_NORMED);
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
matchLoc=minLoc;
int dogrula;
if(matchLoc.x>0){
check_counter=check_counter+1;
}
if(check_counter>20){ // if it stays 20 frames, assume "detected
cout<<"0 number detected"<<endl;
}
rectangle(cropped_bw, matchLoc, Point( matchLoc.x + templ_resized_bw.cols , matchLoc.y + templ_resized_bw.rows ), Scalar::all(100), 1, 8, 0 );
imshow("5",cropped_bw);
if(waitKey(30) == 27)
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}

As I am trying to search specific and same number I found this solution.
Which is comparing two images as if they are same.
#include<opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <sstream>
using namespace cv;
using namespace std;
Mat frame;
Mat img;
Mat templ;
Mat templ_resized;
Mat templ_resized_bw;
Mat result;
cv::Mat sel;
cv::Mat img_final;
//**************
int detect()
{
VideoCapture cap("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/Final/kucukaga2.avi");
if ( !cap.isOpened() )
{
cout << "Cannot open the video file" << endl;
return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
cout << "Frame per seconds : " << fps << endl;
int counter=0;
int check_counter=0;
std::string s;
cv::Rect myROI(702, 476, 11,16); // location of countdown timer
cv::Mat cropped;
templ = imread("/home/semih/Desktop/OPENCV_ON_LINUX/dizifiles/yenisoncalismalar/Final/thresh747.png",CV_LOAD_IMAGE_COLOR);
cv::resize(templ,templ_resized,Size(45,45),CV_INTER_LINEAR); //8 11
Mat cropped_bw;
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
cv::Mat pic;
while(1)
{
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "Cannot read the frame from video file" << endl;
break;
}
counter=counter+1;
cv::Mat croppedRef(frame, myROI);
cvtColor(croppedRef,cropped_bw,CV_RGB2GRAY);
cv::resize(cropped_bw,cropped_bw,Size(45,45),CV_INTER_LINEAR);
cropped_bw = cropped_bw > 200;
cvtColor(templ_resized,templ_resized_bw,CV_RGB2GRAY);
templ_resized_bw=templ_resized_bw>200;
cv::Mat result2;
Mat croppedsimilar;
Mat templ_resized_re;
Mat templ_cvt;
cvtColor(templ_resized, templ_cvt, CV_BGR2GRAY);
cv::resize(templ_cvt,templ_resized_re,Size(45,45),CV_INTER_LINEAR);
cv::resize(cropped_bw,croppedsimilar,Size(45,45),CV_INTER_LINEAR);
templ_resized_re=templ_resized_re>200;
croppedsimilar=croppedsimilar>200;
imshow("111",croppedsimilar);
imshow("222",templ_resized_re);
int threshold = (double)(templ_resized_re.rows * templ_resized_re.cols) * 0.97;
// Search for almost same match
cv::compare(croppedsimilar , templ_resized_re , result2 , cv::CMP_EQ );
int similarPixels = countNonZero(result2);
if ( similarPixels > threshold ) {
cout << "number '0' found !!!!!" << endl;
}
if(waitKey(30) == 27)
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}

Related

frame subtraction in video

I am trying to do Frame subtraction in a video.Steps I am following
Get a image , convert it into grayscale.
Subtract it from previous frame grayscale.
All I see in diff2(and diff also) a complete black image.One observation I made is that pixel value of gray1 and gray2 become equal.
My code
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include <opencv2/video/background_segm.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
int main( int argc, const char** argv )
{
VideoCapture cap(0);
if ( !cap.isOpened() )
{
cout << "Cannot open the web cam" << endl;
return -1;
}
Mat img1,img2,diff,gray1,gray2,diff2;
bool bSuccess = cap.read(img1); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
return -1;
}
cvtColor( img1,gray1, CV_BGR2GRAY );
while (true)
{
bSuccess = cap.read(img2); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
cvtColor( img2,gray2, CV_BGR2GRAY );
absdiff(gray2,gray1,diff);
threshold(diff, diff2, 150, 255, CV_THRESH_BINARY);
cout<<gray2.at<uchar>(100,200) <<endl;
cout<<gray1.at<uchar>(100,200) <<endl;
gray1=gray2;
imshow("1",gray1);
imshow("2",diff2);
if (waitKey(1000) == 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 -1;
}
please try this code. It looks like you're overwriting gray1 so that gray1 and gray2 use the very same data memory positions.
You could either use gray1=gray2.clone(); instead or use some real "swapping" of the buffers instead of overwriting. My code should perform a simple buffer swapping and has some comments about the problem.
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include <opencv2/video/background_segm.hpp>
#include <iostream>
using namespace cv;
using namespace std;
RNG rng(12345);
int main( int argc, const char** argv )
{
VideoCapture cap(0);
if ( !cap.isOpened() )
{
cout << "Cannot open the web cam" << endl;
return -1;
}
Mat img1,img2,diff,gray1,gray2,diff2;
Mat tmp; // used to swap the buffers
bool bSuccess = cap.read(img1); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
return -1;
}
// this will allocate memory of gray1 if not allocated yet
cvtColor( img1,gray1, CV_BGR2GRAY );
while (true)
{
bSuccess = cap.read(img2); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
// memory for gray2 won't be allocated if it is present already => if gray2 and gray1 use the same data memory, you'll overwrite gray1's pixels here and obviously gray1 and gray2 will have the same pixel values then
cvtColor( img2,gray2, CV_BGR2GRAY );
absdiff(gray2,gray1,diff);
threshold(diff, diff2, 150, 255, CV_THRESH_BINARY);
cout<<gray2.at<uchar>(100,200) <<endl;
cout<<gray1.at<uchar>(100,200) <<endl;
// don't lose the memory of gray1
tmp = gray1;
// this means gray1 and gray2 will use the same data memory location
gray1=gray2;
// give gray2 a new data memory location. Since previous gray1 memory is still present but wont be used anymore, use it here.
gray2=tmp;
imshow("1",gray1);
imshow("2",diff2);
if (waitKey(1000) == 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 -1;
}
in addition, a thres difference threshold of 150 might be very high for common tasks, but it might be ok for your special task. Typical difference values/thresholds in background subtraction for foreground extraction are around 20 to 30 from my experience, but at the end it depends on your task/problem/domain.

Improve Prediction Sensivity using SVM with OpenCV

I am trying to classify my images whether characters are printed on surface or not.
For doing it.
First I take surf features of images with real images and manually defect real images to try create bag of words to an xml file and then try to predict.
however unless I use absolutely different image or totally cropped image my SVM classifier predicts as it is correct.
those are the images I used for train
https://www.dropbox.com/sh/xked9ywnibzv3tt/AADC0lP4WYAo3ddEDgvHpFhha/negative?dl=0
Here is my code.
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "opencv2/core/core.hpp"
#include<dirent.h>
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
Ptr<FeatureDetector> detector = FeatureDetector::create("SURF");
Ptr<DescriptorExtractor> descriptors = DescriptorExtractor::create("SURF");
string to_string(const int val) {
int i = val;
std::string s;
std::stringstream out;
out << i;
s = out.str();
return s;
}
Mat compute_features(Mat image) {
vector<KeyPoint> keypoints;
Mat features;
detector->detect(image, keypoints);
KeyPointsFilter::retainBest(keypoints, 1500);
descriptors->compute(image, keypoints, features);
return features;
}
BOWKMeansTrainer addFeaturesToBOWKMeansTrainer(String dir, BOWKMeansTrainer& bowTrainer) {
DIR *dp;
struct dirent *dirp;
struct stat filestat;
dp = opendir(dir.c_str());
Mat features;
Mat img;
string filepath;
#pragma loop(hint_parallel(4))
for (; (dirp = readdir(dp));) {
filepath = dir + dirp->d_name;
cout << "Reading... " << filepath << endl;
if (stat( filepath.c_str(), &filestat )) continue;
if (S_ISDIR( filestat.st_mode )) continue;
img = imread(filepath, 0);
features = compute_features(img);
bowTrainer.add(features);
}
return bowTrainer;
}
void computeFeaturesWithBow(string dir, Mat& trainingData, Mat& labels, BOWImgDescriptorExtractor& bowDE, int label) {
DIR *dp;
struct dirent *dirp;
struct stat filestat;
dp = opendir(dir.c_str());
vector<KeyPoint> keypoints;
Mat features;
Mat img;
string filepath;
#pragma loop(hint_parallel(4))
for (;(dirp = readdir(dp));) {
filepath = dir + dirp->d_name;
cout << "Reading: " << filepath << endl;
if (stat( filepath.c_str(), &filestat )) continue;
if (S_ISDIR( filestat.st_mode )) continue;
img = imread(filepath, 0);
detector->detect(img, keypoints);
bowDE.compute(img, keypoints, features);
trainingData.push_back(features);
labels.push_back((float) label);
}
cout << string( 100, '\n' );
}
int main() {
initModule_nonfree();
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
TermCriteria tc(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 10, 0.001);
int dictionarySize = 1000;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(descriptors, matcher);
string dir = "/positive/", filepath;
DIR *dp;
struct dirent *dirp;
struct stat filestat;
cout << "Add Features to KMeans" << endl;
addFeaturesToBOWKMeansTrainer("/positive/", bowTrainer);
addFeaturesToBOWKMeansTrainer("/negative/", bowTrainer);
cout << endl << "Clustering..." << endl;
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
Mat labels(0, 1, CV_32FC1);
Mat trainingData(0, dictionarySize, CV_32FC1);
cout << endl << "Extract bow features" << endl;
computeFeaturesWithBow("/positive/", trainingData, labels, bowDE, 1);
computeFeaturesWithBow("/negative/", trainingData, labels, bowDE, 0);
CvSVMParams params;
params.kernel_type=CvSVM::LINEAR;
params.svm_type=CvSVM::C_SVC;
params.gamma=5;
params.C=100;
params.term_crit=cvTermCriteria(CV_TERMCRIT_NUMBER,100,0.000001);
CvSVM svm;
cout << endl << "Begin training" << endl;
bool res =svm.train(trainingData,labels,cv::Mat(),cv::Mat(),params);
svm.save("classifier.xml");
//CvSVM svm;
svm.load("classifier.xml");
vector<KeyPoint> cameraKeyPoints;
Mat rotated = imread("test.jpg",0);
Mat featuresFromimage;
detector->detect(rotated, cameraKeyPoints);
bowDE.compute(rotated, cameraKeyPoints, featuresFromimage);
cout <<"anar:"<< svm.predict(featuresFromimage) << endl;
imshow("edges", rotated);
cvWaitKey(0);
return 0;
}
Question 1: since those images are too similiar how can I do prediction like
if similiarity > %80
"correct"
else
"defected"
Question 2 Since this character defection is too rare in a factory it is going to very very tough to get a lot of defected images to train. Manually create defect on this images is a correct solution ? if not what I can actually do ?
Question 3
What kind of preprocessing methods I can actually do on this kind of images to increase accuracy of SVM ?
thank you

face detection using HAAR classifier

Iam working on face detection in openCV with HAAR classifier. Here is my code
#include "stdafx.h"
#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv\cv.h>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
void detectAndDisplay(Mat frame);
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eye_cascade;
string window_name = "Capture- Face detection";
int _tmain(int argc, _TCHAR* argv[])
{
Mat frame = imread("C:/Users/Public/Pictures/Sample Pictures/lena.png");
imshow("original picture", frame);
if (face_cascade.load(face_cascade_name))
{
cout << "\n Error loading " << endl;
}
if (eye_cascade.load(eyes_cascade_name))
{
cout << "\n Error Loading " << endl;
}
if (!frame.empty())
{
detectAndDisplay(frame);
}
waitKey(0);
return 0;
}
void detectAndDisplay(Mat frame)
{
vector<Rect>faces;
imshow("lena.png", frame);
Mat frame_gray;
cvtColor(frame, frame_gray, CV_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
imshow("Gray Color Image", frame_gray);
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(20, 20));
int k = faces.size();
for (size_t i = 0; i <faces.size(); i++)
{
Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5);
ellipse(frame, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 0));
Mat faceROI = frame_gray(faces[i]);
vector<Rect>eyes;
eye_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
for (int j = 0; j < eyes.size(); j++)
{
Point center(faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5);
int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
circle(frame, center, radius, Scalar(0, 0,255), 4, 8, 0);
}
}
imshow(window_name, frame);
}
Here My code is not working. face is not being detected. iam trying get int k=faces.size() which is getting '0' value. what could be the possible error.
That is because your if-condition to load the cascade is not logic:
Yours is:
if (face_cascade.load(face_cascade_name))
{
cout << "\n Error loading " << endl;
}
if (eye_cascade.load(eyes_cascade_name))
{
cout << "\n Error Loading " << endl;
}
But it should be:
if (!face_cascade.load(face_cascade_name))
{
cout << "\n Error loading " << endl;
}
if (!eye_cascade.load(eyes_cascade_name))
{
cout << "\n Error Loading " << endl;
}
You forget the '!' in the conditions.
face_cascade.load(face_cascade_name) obviously returns FALSE when classifier successfully loaded. You can find it in one of the samples provided with OpenCV library facedetect.cpp
This is why you don't see that the loading process failed and you provided wrong path to haarcascade file.

Decode QR code, from low quality image (with ZBar)

I tried to decode QR codes from images like this:
Based on the following code,
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
#include <iostream>
using namespace cv;
using namespace std;
using namespace zbar;
//g++ main.cpp /usr/local/include/ /usr/local/lib/ -lopencv_highgui.2.4.8 -lopencv_core.2.4.8
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
// cap.set(CV_CAP_PROP_FRAME_WIDTH,800);
// cap.set(CV_CAP_PROP_FRAME_HEIGHT,640);
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
ImageScanner scanner;
scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1);
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
Mat grey;
cvtColor(frame,grey,CV_BGR2GRAY);
int width = frame.cols;
int height = frame.rows;
uchar *raw = (uchar *)grey.data;
// wrap image data
Image image(width, height, "Y800", raw, width * height);
// scan the image for barcodes
int n = scanner.scan(image);
// extract results
for(Image::SymbolIterator symbol = image.symbol_begin();
symbol != image.symbol_end();
++symbol) {
vector<Point> vp;
// do something useful with results
cout << "decoded " << symbol->get_type_name() << " symbol \"" << symbol->get_data() << '"' <<" "<< endl;
int n = symbol->get_location_size();
for(int i=0;i<n;i++){
vp.push_back(Point(symbol->get_location_x(i),symbol->get_location_y(i)));
}
RotatedRect r = minAreaRect(vp);
Point2f pts[4];
r.points(pts);
for(int i=0;i<4;i++){
line(frame,pts[i],pts[(i+1)%4],Scalar(255,0,0),3);
}
//cout<<"Angle: "<<r.angle<<endl;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
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;
}
The naive ZLib approach fails 100%. But the zxing barcode scanner app can decode it from the computer screen, so it's definitely contains all the necessary information.
Any idea how to make the scanning more robust?

opencv cvblob -- render blobs other than white

I am trying to detect objects with cvblob. Somehow, my code only marks the white objects. How to mark objects of other colors, like a can of beer or a bottle of water.
Here is my code:
#include "highgui.h"
#include "cv.h"
#include "cvaux.h"
#include "iostream"
#include <stdio.h>
#include <ctype.h>
#include <cvblob.h>
using namespace cv;
using namespace std;
using namespace cvb;
int main(int argc, char** argv) {
CvTracks tracks;
cvNamedWindow("frame", CV_WINDOW_AUTOSIZE);
cvMoveWindow("frame", 50, 100);
CvCapture* capture;
IplImage* frame = 0;
capture = cvCreateCameraCapture( 0 ); //capture frames from cam on index 0: /dev/video0/
if (!capture) {
return -1;
}
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);
frame = cvQueryFrame(capture);
while(frame) {
IplImage *gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
cvCvtColor(frame, gray, CV_BGR2GRAY);
cvThreshold(gray, gray, 150, 255, CV_THRESH_BINARY);
IplImage *labelImg=cvCreateImage(cvGetSize(gray), IPL_DEPTH_LABEL, 1);
CvBlobs blobs;
unsigned int result=cvLabel(gray, labelImg, blobs);
cvFilterByArea(blobs, 500, 1000000);
// cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_CENTROID);
cvUpdateTracks(blobs, tracks, 200., 5);
cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);
for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it) {
cout << "Blob #" << it->second->label << ": Area=" << it->second->area << ", Centroid=(" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << endl;
}
cvShowImage("frame", frame);
cout << "----------------------------" << endl;
frame = cvQueryFrame(capture);
char c = cvWaitKey(10);
if(c==27)
break;
}
}
Any tip is appreciated.
Milo
That's the option by default and you cannot change it if you don't change the source code in cvblob library.
If you really want to change this is so easy, you can create a copy of the same method adding a new input var like CvScalar to select output color. It's so easy.
The method cvRenderBlob will be in cvcontour.cpp.
I've been made many improvement in cvblob library and in next months I will push it to the creator.
Try adding:
"cvInRangeS(hsvframe,cvScalar(23,41,133),cvScalar(40,150,255),threshy);//for yellow"
Before Filtering the blobs. Its a range of HSV(instead of RGB) values that defines the threshold of the desire color.
Hope it helps.

Resources