From 9b382d07f6e460511f2eaa79dc262d0911b74ab9 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 27 Apr 2012 16:10:10 +0000 Subject: [PATCH] modified data matrix detection interface (that does not use any new data structures). Added Python sample for data matrix detection. Ticket #1664 --- modules/core/include/opencv2/core/core.hpp | 4 +- .../include/opencv2/objdetect/objdetect.hpp | 17 +-- modules/objdetect/src/datamatrix.cpp | 114 ++++++++++------- samples/cpp/video_dmtx.cpp | 141 +++++++++++---------- samples/python2/video_dmtx.py | 68 ++++++++++ 5 files changed, 215 insertions(+), 129 deletions(-) create mode 100644 samples/python2/video_dmtx.py diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index f284ac7..a2bb752 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -2142,11 +2142,11 @@ CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx); CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst); CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst); -CV_EXPORTS_W void hconcat(InputArray src, OutputArray dst); +CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst); CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst); CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst); -CV_EXPORTS_W void vconcat(InputArray src, OutputArray dst); +CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst); //! computes bitwise conjunction of the two arrays (dst = src1 & src2) CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2, diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index e3eb07d..130cc1b 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -586,16 +586,13 @@ public: }; - - -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); -CV_EXPORTS void drawDataMatrixCodes(const std::vector& codes, Mat& drawImage); +CV_EXPORTS_W void findDataMatrix(InputArray image, + CV_OUT vector& codes, + OutputArray corners=noArray(), + OutputArrayOfArrays dmtx=noArray()); +CV_EXPORTS_W void drawDataMatrixCodes(InputOutputArray image, + const vector& codes, + InputArray corners); } /****************************************************************************************\ diff --git a/modules/objdetect/src/datamatrix.cpp b/modules/objdetect/src/datamatrix.cpp index 549d77a..a4258bd 100644 --- a/modules/objdetect/src/datamatrix.cpp +++ b/modules/objdetect/src/datamatrix.cpp @@ -496,60 +496,80 @@ endo: ; // end search for this o namespace cv { -namespace + +void findDataMatrix(InputArray _image, + vector& codes, + OutputArray _corners, + OutputArrayOfArrays _dmtx) { - struct CvDM2DM_transform - { - DataMatrixCode operator()(CvDataMatrixCode& cvdm) + Mat image = _image.getMat(); + CvMat m(image); + deque rc = cvFindDataMatrix(&m); + int i, n = (int)rc.size(); + Mat corners; + + if( _corners.needed() ) { - DataMatrixCode dm; - 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; + _corners.create(n, 4, CV_32SC2); + corners = _corners.getMat(); } - }; - - struct DrawDataMatrixCode - { - DrawDataMatrixCode(cv::Mat& image):image(image){} - void operator()(const DataMatrixCode& code) + + if( _dmtx.needed() ) + _dmtx.create(n, 1, CV_8U); + + codes.resize(n); + + for( i = 0; i < n; i++ ) { - 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); + CvDataMatrixCode& rc_i = rc[i]; + codes[i] = string(rc_i.msg); + + if( corners.data ) + { + const Point* srcpt = (Point*)rc_i.corners->data.ptr; + Point* dstpt = (Point*)corners.ptr(i); + for( int k = 0; k < 4; k++ ) + dstpt[k] = srcpt[k]; + } + cvReleaseMat(&rc_i.corners); + + if( _dmtx.needed() ) + { + _dmtx.create(rc_i.original->rows, rc_i.original->cols, rc_i.original->type, i); + Mat dst = _dmtx.getMat(i); + Mat(rc_i.original).copyTo(dst); + } + cvReleaseMat(&rc_i.original); } - cv::Mat& image; - - DrawDataMatrixCode& operator=(const DrawDataMatrixCode&); - }; } -void findDataMatrix(const cv::Mat& image, std::vector& codes) +void drawDataMatrixCodes(InputOutputArray _image, + const vector& codes, + InputArray _corners) { - 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)); + Mat image = _image.getMat(); + Mat corners = _corners.getMat(); + int i, n = corners.rows; + + if( n > 0 ) + { + CV_Assert( corners.depth() == CV_32S && + corners.cols*corners.channels() == 8 && + n == (int)codes.size() ); + } + + for( i = 0; i < n; i++ ) + { + Scalar c(0, 255, 0); + Scalar c2(255, 0,0); + const Point* pt = (const Point*)corners.ptr(i); + + for( int k = 0; k < 4; k++ ) + line(image, pt[k], pt[(k+1)%4], c); + //int baseline = 0; + //Size sz = getTextSize(code_text, CV_FONT_HERSHEY_SIMPLEX, 1, 1, &baseline); + putText(image, codes[i], pt[0], CV_FONT_HERSHEY_SIMPLEX, 0.8, c2, 1, CV_AA, false); + } } - + } diff --git a/samples/cpp/video_dmtx.cpp b/samples/cpp/video_dmtx.cpp index 946aa35..a3981c9 100644 --- a/samples/cpp/video_dmtx.cpp +++ b/samples/cpp/video_dmtx.cpp @@ -21,80 +21,81 @@ 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] << "