From: Ethan Rublee Date: Wed, 25 May 2011 00:23:50 +0000 (+0000) Subject: adding c++ interface to the datamtrix codes of j. X-Git-Tag: accepted/2.0/20130307.220821~3048 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=355ad2993a7deb57cf8e69a8c5daf0424ffeb860;p=profile%2Fivi%2Fopencv.git adding c++ interface to the datamtrix codes of j. --- diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 5309ae5..97c75e6 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -690,7 +690,14 @@ protected: std::vector objectClassNames; std::vector 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& codes); +void drawDataMatrixCodes(const std::vector& 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 -CV_EXPORTS std::deque cvFindDataMatrix(CvMat *im); +#include +CV_EXPORTS std::deque cvFindDataMatrix(CvMat *im); #endif #endif diff --git a/modules/objdetect/src/datamatrix.cpp b/modules/objdetect/src/datamatrix.cpp index 15cdc80..7f051a2 100644 --- a/modules/objdetect/src/datamatrix.cpp +++ b/modules/objdetect/src/datamatrix.cpp @@ -5,11 +5,15 @@ #endif #include +#include + using namespace std; #undef NDEBUG #include + + 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 trailto(CvMat *v, int x, int y, CvMat *terminal) return r; } -deque cvFindDataMatrix(CvMat *im) +deque cvFindDataMatrix(CvMat *im) { #if CV_SSE2 int r = im->rows; @@ -411,7 +421,7 @@ deque 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 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 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 rc; + deque 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 rc; + deque rc; return rc; #endif } + +#include +#include + +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(0,0); + dm.corners[1] = c.at(1,0); + dm.corners[2] = c.at(2,0); + dm.corners[3] = c.at(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& codes) +{ + CvMat m(image); + deque rc = cvFindDataMatrix(&m); + codes.clear(); + codes.resize(rc.size()); + std::transform(rc.begin(),rc.end(),codes.begin(),CvDM2DM_transform()); +} + +void drawDataMatrixCodes(const std::vector& codes, Mat& drawImage) +{ + std::for_each(codes.begin(),codes.end(),DrawDataMatrixCode(drawImage)); +} + +} diff --git a/modules/python/src1/cv.cpp b/modules/python/src1/cv.cpp index 3ed49e4..7a65891 100644 --- a/modules/python/src1/cv.cpp +++ b/modules/python/src1/cv.cpp @@ -3686,12 +3686,12 @@ static PyObject *pyfinddatamatrix(PyObject *self, PyObject *args) CvMat *image; if (!convert_to_CvMat(pyim, &image, "image")) return NULL; - std::deque codes; + std::deque 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))); } diff --git a/samples/cpp/video_dmtx.cpp b/samples/cpp/video_dmtx.cpp new file mode 100644 index 0000000..ea2a575 --- /dev/null +++ b/samples/cpp/video_dmtx.cpp @@ -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 +#include +#include +#include +#include + +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] << "