adding c++ interface to the datamtrix codes of j.
This commit is contained in:
parent
89b5f40ce3
commit
355ad2993a
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
94
samples/cpp/video_dmtx.cpp
Normal file
94
samples/cpp/video_dmtx.cpp
Normal 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user