adding c++ interface to the datamtrix codes of j.

This commit is contained in:
Ethan Rublee 2011-05-25 00:23:50 +00:00
parent 89b5f40ce3
commit 355ad2993a
4 changed files with 200 additions and 24 deletions

View File

@ -690,7 +690,14 @@ protected:
std::vector<std::string> objectClassNames;
std::vector<DOTTemplate> dotTemplates;
};
struct CV_EXPORTS DataMatrixCode {
char msg[4]; //TODO std::string
Mat original;
Point corners[4]; //TODO vector
};
CV_EXPORTS void findDataMatrix(const Mat& image, std::vector<DataMatrixCode>& codes);
void drawDataMatrixCodes(const std::vector<DataMatrixCode>& codes, Mat& drawImage);
}
/****************************************************************************************\
@ -699,15 +706,14 @@ protected:
typedef unsigned char uint8;
class CV_EXPORTS DataMatrixCode {
public:
struct CV_EXPORTS CvDataMatrixCode {
char msg[4];
CvMat *original;
CvMat *corners;
};
#include <deque>
CV_EXPORTS std::deque<DataMatrixCode> cvFindDataMatrix(CvMat *im);
CV_EXPORTS std::deque<CvDataMatrixCode> cvFindDataMatrix(CvMat *im);
#endif
#endif

View File

@ -5,11 +5,15 @@
#endif
#include <deque>
#include <algorithm>
using namespace std;
#undef NDEBUG
#include <assert.h>
class Sampler {
public:
CvMat *im;
@ -18,7 +22,6 @@ public:
CvMat *perim;
CvPoint fcoord(float fx, float fy);
CvPoint coord(int ix, int iy);
Sampler() {}
Sampler(CvMat *_im, CvPoint _o, CvPoint _c, CvPoint _cc);
uint8 getpixel(int ix, int iy);
int isinside(int x, int y);
@ -26,6 +29,8 @@ public:
int hasbars();
void timing();
CvMat *extract();
Sampler():im(0),perim(0){}
~Sampler(){}
};
class code { // used in this file only
@ -128,16 +133,21 @@ CvPoint Sampler::coord(int ix, int iy)
uint8 Sampler::getpixel(int ix, int iy)
{
CvPoint pt = coord(ix, iy);
// printf("%d,%d\n", pt.x, pt.y);
return *cvPtr2D(im, pt.y, pt.x);
if ((0 <= pt.x) && (pt.x < im->cols) && (0 <= pt.y) && (pt.y < im->rows))
return *cvPtr2D(im, pt.y, pt.x);
else
return 0;
}
int Sampler::isinside(int x, int y)
{
CvPoint2D32f fp;
fp.x = (float)x;
fp.y = (float)y;
return cvPointPolygonTest(perim, fp, 0) < 0;
CvPoint2D32f pt;
pt.x = (float)x;
pt.y = (float)y;
if ((0 <= pt.x) && (pt.x < im->cols) && (0 <= pt.y) && (pt.y < im->rows))
return cvPointPolygonTest(perim, pt, 0) < 0;
else
return 0;
}
int Sampler::overlap(Sampler &other)
@ -329,7 +339,7 @@ static deque<CvPoint> trailto(CvMat *v, int x, int y, CvMat *terminal)
return r;
}
deque <DataMatrixCode> cvFindDataMatrix(CvMat *im)
deque <CvDataMatrixCode> cvFindDataMatrix(CvMat *im)
{
#if CV_SSE2
int r = im->rows;
@ -411,7 +421,7 @@ deque <DataMatrixCode> cvFindDataMatrix(CvMat *im)
__m128 iscand = _mm_and_ps(_mm_cmpgt_ps(cmag, Kf(30)), _mm_cmpgt_ps(ccmag, Kf(30)));
iscand = _mm_and_ps(iscand, _mm_cmpgt_ps(_mm_mul_ps(_mm_min_ps(cmag, ccmag), Kf(1.1f)), _mm_max_ps(cmag, ccmag)));
iscand = _mm_and_ps(iscand, _mm_cmplt_ps(_mm_abs_ps(dot), Kf(0.25f)));
iscand = _mm_and_ps(iscand, _mm_cmplt_ps(_mm_abs_ps(dot), Kf(0.25f)));
unsigned int CV_DECL_ALIGNED(16) result[4];
_mm_store_ps((float*)result, iscand);
@ -441,7 +451,10 @@ deque <DataMatrixCode> cvFindDataMatrix(CvMat *im)
Sampler sa(im, o, ptc[j], ptcc[k]);
for (i = 0; i < codes.size(); i++) {
if (sa.overlap(codes[i].sa))
{
cvReleaseMat(&sa.perim);
goto endo;
}
}
if (codes.size() > 0) {
printf("searching for more\n");
@ -450,21 +463,23 @@ deque <DataMatrixCode> cvFindDataMatrix(CvMat *im)
codes.push_back(cc);
goto endo;
}
cvReleaseMat(&sa.perim);
}
}
endo: ; // end search for this o
}
cvFree(&thresh);
cvFree(&vecpic);
cvFree(&vc);
cvFree(&vcc);
cvFree(&cxy);
cvFree(&ccxy);
cvReleaseMat(&thresh);
cvReleaseMat(&vecpic);
cvReleaseMat(&vc);
cvReleaseMat(&vcc);
cvReleaseMat(&cxy);
cvReleaseMat(&ccxy);
deque <DataMatrixCode> rc;
deque <CvDataMatrixCode> rc;
for (i = 0; i < codes.size(); i++) {
DataMatrixCode cc;
CvDataMatrixCode cc;
strcpy(cc.msg, codes[i].msg);
cc.original = codes[i].original;
cc.corners = codes[i].sa.perim;
@ -472,7 +487,68 @@ endo: ; // end search for this o
}
return rc;
#else
deque <DataMatrixCode> rc;
deque <CvDataMatrixCode> rc;
return rc;
#endif
}
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
namespace cv
{
namespace
{
struct CvDM2DM_transform
{
DataMatrixCode operator()(CvDataMatrixCode& cvdm)
{
DataMatrixCode dm;
std::memcpy(dm.msg,cvdm.msg,sizeof(cvdm.msg));
dm.original = cv::Mat(cvdm.original,true);
cvReleaseMat(&cvdm.original);
cv::Mat c(cvdm.corners,true);
dm.corners[0] = c.at<Point>(0,0);
dm.corners[1] = c.at<Point>(1,0);
dm.corners[2] = c.at<Point>(2,0);
dm.corners[3] = c.at<Point>(3,0);
cvReleaseMat(&cvdm.corners);
return dm;
}
};
struct DrawDataMatrixCode
{
DrawDataMatrixCode(cv::Mat& image):image(image){}
void operator()(const DataMatrixCode& code)
{
Scalar c(0, 255, 0);
Scalar c2(255, 0,0);
line(image, code.corners[0], code.corners[1], c);
line(image, code.corners[1], code.corners[2], c);
line(image, code.corners[2], code.corners[3], c);
line(image, code.corners[3], code.corners[0], c);
string code_text(code.msg,4);
int baseline = 0;
Size sz = getTextSize(code_text, CV_FONT_HERSHEY_SIMPLEX, 1, 1, &baseline);
putText(image, code_text, code.corners[0], CV_FONT_HERSHEY_SIMPLEX, 0.8, c2, 1, CV_AA, false);
}
cv::Mat& image;
};
}
void findDataMatrix(const cv::Mat& image, std::vector<DataMatrixCode>& codes)
{
CvMat m(image);
deque <CvDataMatrixCode> rc = cvFindDataMatrix(&m);
codes.clear();
codes.resize(rc.size());
std::transform(rc.begin(),rc.end(),codes.begin(),CvDM2DM_transform());
}
void drawDataMatrixCodes(const std::vector<DataMatrixCode>& codes, Mat& drawImage)
{
std::for_each(codes.begin(),codes.end(),DrawDataMatrixCode(drawImage));
}
}

View File

@ -3686,12 +3686,12 @@ static PyObject *pyfinddatamatrix(PyObject *self, PyObject *args)
CvMat *image;
if (!convert_to_CvMat(pyim, &image, "image")) return NULL;
std::deque <DataMatrixCode> codes;
std::deque <CvDataMatrixCode> codes;
ERRWRAP(codes = cvFindDataMatrix(image));
PyObject *pycodes = PyList_New(codes.size());
for (size_t i = 0; i < codes.size(); i++) {
DataMatrixCode *pc = &codes[i];
CvDataMatrixCode *pc = &codes[i];
PyList_SetItem(pycodes, i, Py_BuildValue("(sOO)", pc->msg, FROM_CvMat(pc->corners), FROM_CvMat(pc->original)));
}

View File

@ -0,0 +1,94 @@
/*
* starter_video.cpp
*
* Created on: Nov 23, 2010
* Author: Ethan Rublee
*
* A starter sample for using opencv, get a video stream and display the images
* easy as CV_PI right?
*/
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace cv;
using namespace std;
//hide the local functions in an anon namespace
namespace
{
void help(char** av)
{
cout << "\nThis program justs gets you started reading images from video\n"
"Usage:\n./" << av[0] << " <video device number>\n" << "q,Q,esc -- quit\n"
<< "space -- save frame\n\n"
<< "\tThis is a starter sample, to get you up and going in a copy pasta fashion\n"
<< "\tThe program captures frames from a camera connected to your computer.\n"
<< "\tTo find the video device number, try ls /dev/video* \n"
<< "\tYou may also pass a video file, like my_vide.avi instead of a device number"
<< endl;
}
int process(VideoCapture& capture)
{
std::vector<DataMatrixCode> codes;
int n = 0;
char filename[200];
string window_name = "video | q or esc to quit";
cout << "press space to save a picture. q or esc to quit" << endl;
namedWindow(window_name, CV_WINDOW_KEEPRATIO); //resizable window;
Mat frame;
for (;;)
{
capture >> frame;
if (frame.empty())
continue;
cv::Mat gray;
cv::cvtColor(frame,gray,CV_RGB2GRAY);
findDataMatrix(gray, codes);
drawDataMatrixCodes(codes, frame);
imshow(window_name, frame);
char key = (char) waitKey(5); //delay N millis, usually long enough to display and capture input
switch (key)
{
case 'q':
case 'Q':
case 27: //escape key
return 0;
case ' ': //Save an image
sprintf(filename, "filename%.3d.jpg", n++);
imwrite(filename, frame);
cout << "Saved " << filename << endl;
break;
default:
break;
}
}
return 0;
}
}
int main(int ac, char** av)
{
if (ac != 2)
{
help(av);
return 1;
}
std::string arg = av[1];
VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file
if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param
capture.open(atoi(arg.c_str()));
if (!capture.isOpened())
{
cerr << "Failed to open a video device or video file!\n" << endl;
help(av);
return 1;
}
return process(capture);
}