opencv cvblob -- render blobs other than white - opencv

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.

Related

how to track objects within the ROI using dlib?

I'm trying to get the stream and defining the ROI and tracking an object within ROI using dlib correlation tracker but there is a error in compilation, not found any code or explanation which can describe any solution of this error. Thanks in advance.
cvcap.cpp
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
CvCapture* camera = cvCaptureFromFile(argv[1]);
if (camera==NULL)
printf("camera is null\n");
else
printf("camera is not null\n");
cvNamedWindow("CvCapture");
while (cvWaitKey(1000)!=atoi("q")){
double t1 = (double)cvGetTickCount();
IplImage *img = cvQueryFrame(camera);
cvSetImageROI(img, cvRect(140, 150, 340, 150));
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
cvCopy(img, img1, NULL);
cvResetImageROI(img);
cvShowImage("ROI",img1);
correlation_tracker tracker;
tracker.start_track(img1, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img1);
win.set_image(img1);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cin.get();
double t2=(double)cvGetTickCount();
printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("CvCapture",img1);
}
cvReleaseCapture(&camera);
}
the error is :
In file included from dlib/image_processing.h:24:0,
from cvcap.cpp:3:
dlib/image_processing/correlation_tracker.h: In instantiation of ‘dlib::point_transform_affine dlib::correlation_tracker::make_chip(const image_type&,
dlib::drectangle, std::vector<dlib::matrix<std::complex<double> > >&) const [with image_type = _IplImage*]’:
dlib/image_processing/correlation_tracker.h:65:47: required from ‘void dlib::correlation_tracker::start_track(const image_type&, const dlib::drectang
le&) [with image_type = _IplImage*]’
cvcap.cpp:36:70: required from here
dlib/image_processing/correlation_tracker.h:301:67: error: invalid use of incomplete type ‘struct dlib::image_traits<_IplImage*>’
typedef typename image_traits<image_type>::pixel_type pixel_type;
Update
i edited my code and now it is compiling but when i'm running my code, tracking box appears but it is not tracking the objects.
for(;;) {
if(!vcap.read(image)) {
std::cout << "No frame" << std::endl;
break;
} else {
std::cout << "Starting" << std::endl;
array2d<rgb_pixel> img;
assign_image(img, cv_image<rgb_pixel>(image));
tracker.start_track(img, centered_rect(point(413,260), 98, 126));
for (unsigned long i = 0; i < img.size(); i++) {
tracker.update(img);
win.set_image(img);
win.clear_overlay();
win.add_overlay(tracker.get_position());
}
}
}
You're passing an IplImage to the dlib routine. But if you look at the docs it says you have to convert your opencv images to cv_images before passing them to dlib functions. And you can see this with the error pointing out IplImage doesn't have a pixel_type trait. A fix would be.
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
...
correlation_tracker tracker;
// Not sure if the tracker wants a single channel image
// change rgb_alpha_pixel to uchar in that case.
tracker.start_track(dlib::cv_image<dlib::rgb_alpha_pixel>(img1), centered_rect(point(120,100), 80, 150));
Pixel types and the Correlation tracker
EDIT: Passed your stuff to opencv 3 and this is compiling for me. Do you really need to use opencv 2?
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
#include <dlib/opencv/cv_image.h>
using namespace cv;
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
VideoCapture cap(0);
Mat frame;
while (cap.read(frame)) {
cvtColor(frame, frame, CV_RGB2GRAY);
cv_image<unsigned char> img(frame);
correlation_tracker tracker;
tracker.start_track(img, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img);
win.set_image(img);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cv::waitKey(0);
}
}
and with an uglier opencv 2..
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include "dlib/image_processing.h"
#include "dlib/gui_widgets.h"
#include "dlib/image_io.h"
#include "dlib/dir_nav.h"
#include <dlib/opencv/cv_image.h>
using namespace cv;
using namespace dlib;
using namespace std;
int main(int argc, char * argv[]){
CvCapture* camera = cvCaptureFromFile(argv[1]);
if (camera==NULL)
printf("camera is null\n");
else
printf("camera is not null\n");
cvNamedWindow("CvCapture");
while (cvWaitKey(1000)!=atoi("q")) {
double t1 = (double)cvGetTickCount();
IplImage *img = cvQueryFrame(camera);
cvSetImageROI(img, cvRect(140, 150, 340, 150));
IplImage *img1 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
cvCopy(img, img1, NULL);
cvResetImageROI(img);
cvShowImage("ROI",img1);
cvCvtColor(img1, img1, CV_RGB2GRAY);
cv_image<unsigned char> img2(img1);
correlation_tracker tracker;
tracker.start_track(img2, centered_rect(point(120,100), 80, 150));
image_window win;
tracker.update(img2);
win.set_image(img2);
win.clear_overlay();
win.add_overlay(tracker.get_position());
cout << "hit enter to process next frame" << endl;
cin.get();
double t2=(double)cvGetTickCount();
printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("CvCapture",img1);
}
cvReleaseCapture(&camera);
}
As you see the error came exactly from what I told you before.

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.

How to detect specific number from image with 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;
}

Grabbing Pixel data from a video strem

I am having trouble if understanding certain coding i am sorry if this comes off as stupid but i have a code to capture a video from my webcam i want to get the RGB valuee from the frame, if this is impossible would have to to save a frame as a picture and then get values from it?
const char window_name[]="Webcam";
int main(int argc, char* argv[])
{
/* attempt to capture from any connected device */
CvCapture *capture=cvCaptureFromCAM(CV_CAP_ANY);
if(!capture)
{
printf("Failed to initialise webcam\n");
return -1;
}
/* create the output window */
cvNamedWindow(window_name, CV_WINDOW_NORMAL);
do
{
/* attempt to grab a frame */
IplImage *frame=cvQueryFrame(capture);
if(!frame)
{
printf("Failed to get frame\n");
break;
}
COLORREF myColAbsolute = GetPixel(frame, 10,10);//error in saying frame is not compatible with HDC.
cout << "Red - " << (int)GetRValue(myColAbsolute) << endl;
cout << "Green - " << (int)GetGValue(myColAbsolute) << endl;
cout << "Blue - " << (int)GetBValue(myColAbsolute) << endl;
/* show the frame */
cvShowImage(window_name, frame);
ha ! ( obviously caught with a copy & paste bummer )
GetPixel() is a windows function, not an opencv one. same for GetRValue() and sisters.
you'd use them in the native win32 api, to get a pixel from an HDC, but it won't work with opencv/highgui, since neither HDC, nor HWND are exposed.
since you're obviously a beginner(nothing wrong with that, again!) let me try to talk you out of using the old, 1.0 opencv api(IplImages, cv*Functions) as well,
you should be using the new one(cv::Mat, namespace cv::Functions) instead.
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat frame;
namedWindow("video", 1);
VideoCapture cap(0);
while ( cap.isOpened() )
{
cap >> frame;
if(frame.empty()) break;
int x=3, y=5;
// Ladies and Gentlemen, the PIXEL!
Vec3b pixel = frame.at<Vec3b>(y,x); // row,col, not x,y!
cerr << "b:" << int(pixel[0]) << " g:" << int(pixel[1]) << " r:" << int(pixel[2]) << endl;
imshow("video", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}

Convert IplImage to CvMat

Here is the gpu surf code:
#include <iostream>
#include <iomanip>
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/imgproc/imgproc_c.h>
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
using namespace std;
using namespace cv;
using namespace cv::gpu;
void help()
{
cout << "\nThis program demonstrates using SURF_GPU features detector, descriptor extractor and BruteForceMatcher_GPU" << endl;
cout << "\nUsage:\n\tmatcher_simple_gpu <image1> <image2>" << endl;
}
int main(int argc, char* argv[])
{
GpuMat img1(imread("C:\\OpenCV2.3\\opencv2.3\\bin\\Debug\\tsucuba_left.png", CV_LOAD_IMAGE_GRAYSCALE));
SURF_GPU surf;
// detecting keypoints & computing descriptors
GpuMat keypoints1GPU, keypoints2GPU;
GpuMat descriptors1GPU, descriptors2GPU;
surf(img1, GpuMat(), keypoints1GPU, descriptors1GPU);
cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl;
//cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl;
CvCapture* capture = cvCaptureFromCAM(0);
int frame_width = (int) cvGetCaptureProperty(capture, 320);
int frame_height = (int) cvGetCaptureProperty(capture, 240);
cout<<"frames done\n";
GpuMat frame_gpu = GpuMat(frame_width, frame_height, CV_8UC3);
GpuMat frame_gpu_cvt = GpuMat(frame_width, frame_height, CV_8UC1);
cout<<"gpu frmes loaded\n";
IplImage* frame;
while(1)
{
frame =cvQueryFrame(capture);
CvMat* image = cvCreateMat(frame->height, frame->width, CV_8UC1);
/*CvMat* image = cvCreateMatHeader(frame->height, frame->width, CV_8UC1);
image->step = 4 * (image->cols * CV_ELEM_SIZE1(image->type) * CV_MAT_CN(image->type) / 4 + 1);//critical
cvCreateData(image);*/
cvInitMatHeader( image, frame->width, frame->height, CV_8UC1,frame->imageData);
// cvConvert( frame, image );
//cvCvtColor( frame, image, CV_RGB2GRAY );
cvConvertImage( frame, image, CV_RGB2GRAY);
namedWindow("aa", 1);
cvShowImage("aa", frame);
frame_gpu.upload(image);
cout<<"frame uploaded\n";
surf(frame_gpu, GpuMat(), keypoints2GPU, descriptors2GPU);
cout<<"surf done\n";
// matching descriptors
BruteForceMatcher_GPU< L2<float> > matcher;
GpuMat trainIdx, distance;
matcher.matchSingle(descriptors1GPU, descriptors2GPU, trainIdx, distance);
cout<<"match done\n";
// downloading results
vector<KeyPoint> keypoints1, keypoints2;
vector<float> descriptors1, descriptors2;
vector<DMatch> matches;
surf.downloadKeypoints(keypoints1GPU, keypoints1);
surf.downloadKeypoints(keypoints2GPU, keypoints2);
surf.downloadDescriptors(descriptors1GPU, descriptors1);
surf.downloadDescriptors(descriptors2GPU, descriptors2);
BruteForceMatcher_GPU< L2<float> >::matchDownload(trainIdx, distance, matches);
// drawing the results
Mat img_matches;
drawMatches(img1, keypoints1, frame_gpu, keypoints2, matches, img_matches);
cout<<"match done\n";
namedWindow("matches", 1);
imshow("matches", img_matches);
cvReleaseMat(&image);
frame_gpu.release();
cvReleaseImage(&frame);
img_matches.release();
cout<<"deallocation done\n";
waitKey(0);
}
cvReleaseCapture(&capture);
cout<<"work done";
return 0;
}
We don't get correct image in frame_gpu,so there is problem in getting image from frame,we printed frame using: cvShowImage("aa", frame); but instead of frame if we try image there is just blank screen
Use your IplImage for counting, and then convert it to a Mat (in C++) with this constructor:
Mat(const IplImage* img, bool copyData=false);
So you would just do:
Mat myMat(img);
That would make your matrix. You would use it in the tracking section of your program!
NOTE: Data is not copied. You can set the copyData parameter to true, though, if you want data to be copied.
Try something like this:
IplImage* frame;
// here load your frame with some image
// convert to cv::Mat and show the converted image
cv::Mat image(frame);
cv::imshow("Image Window", image)
That's how IplImage can be converted to cv::Mat and displayed.
For conversion to and from cvMat, you will find all the details here:
http://wangpengnorman.blogspot.com/2009/06/transform-between-cvmat-and-iplimage.html

Resources