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,
};
-
-
-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);
-CV_EXPORTS void drawDataMatrixCodes(const std::vector<DataMatrixCode>& codes, Mat& drawImage);
+CV_EXPORTS_W void findDataMatrix(InputArray image,
+ CV_OUT vector<string>& codes,
+ OutputArray corners=noArray(),
+ OutputArrayOfArrays dmtx=noArray());
+CV_EXPORTS_W void drawDataMatrixCodes(InputOutputArray image,
+ const vector<string>& codes,
+ InputArray corners);
}
/****************************************************************************************\
namespace cv
{
-namespace
+
+void findDataMatrix(InputArray _image,
+ vector<string>& codes,
+ OutputArray _corners,
+ OutputArrayOfArrays _dmtx)
{
- struct CvDM2DM_transform
- {
- DataMatrixCode operator()(CvDataMatrixCode& cvdm)
+ Mat image = _image.getMat();
+ CvMat m(image);
+ deque <CvDataMatrixCode> 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<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;
+ _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<DataMatrixCode>& codes)
+void drawDataMatrixCodes(InputOutputArray _image,
+ const vector<string>& codes,
+ InputArray _corners)
{
- 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));
+ 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);
+ }
}
-
+
}
//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"
- << "\n"
- << "DATA:\n"
- << "Generate a datamatrix from from http://datamatrix.kaywa.com/ \n"
- << " NOTE: This only handles strings of len 3 or less\n"
- << " Resize the screen to be large enough for your camera to see, and it should find an read it.\n\n"
- << 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())
- break;
- 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)
+ void help(char** av)
{
- 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;
+ 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"
+ << "\n"
+ << "DATA:\n"
+ << "Generate a datamatrix from from http://datamatrix.kaywa.com/ \n"
+ << " NOTE: This only handles strings of len 3 or less\n"
+ << " Resize the screen to be large enough for your camera to see, and it should find an read it.\n\n"
+ << endl;
}
- }
- return 0;
-}
-
+
+ int process(VideoCapture& capture)
+ {
+ 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())
+ break;
+ cv::Mat gray;
+ cv::cvtColor(frame,gray,CV_RGB2GRAY);
+ vector<string> codes;
+ Mat corners;
+ findDataMatrix(gray, codes, corners);
+ drawDataMatrixCodes(frame, codes, corners);
+ 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);
+
+ 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);
}
--- /dev/null
+help='''
+Data matrix detector sample.
+Usage:
+ video_dmtx {<video device number>|<video file name>}
+
+ Generate a datamatrix from from http://datamatrix.kaywa.com/ and print it out.
+ NOTE: This only handles data matrices, generated for text strings of max 3 characters
+
+ Resize the screen to be large enough for your camera to see, and it should find an read it.
+
+Keyboard shortcuts:
+
+ q or ESC - exit
+ space - save current image as datamatrix<frame_number>.jpg
+'''
+
+import cv2
+import numpy as np
+import sys
+
+def data_matrix_demo(cap):
+ window_name = "Data Matrix Detector"
+ frame_number = 0
+ need_to_save = False
+
+ while 1:
+ ret, frame = cap.read()
+ if not ret:
+ break
+
+ gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
+ codes, corners, dmtx = cv2.findDataMatrix(gray)
+
+ cv2.drawDataMatrixCodes(frame, codes, corners)
+ cv2.imshow(window_name, frame)
+
+ key = cv2.waitKey(30)
+ c = chr(key & 255)
+ if c in ['q', 'Q', chr(27)]:
+ break
+
+ if c == ' ':
+ need_to_save = True
+
+ if need_to_save and codes:
+ filename = ("datamatrix%03d.jpg" % frame_number)
+ cv2.imwrite(filename, frame)
+ print "Saved frame to " + filename
+ need_to_save = False
+
+ frame_number += 1
+
+
+if __name__ == '__main__':
+ print help
+
+ if len(sys.argv) == 1:
+ cap = cv2.VideoCapture(0)
+ else:
+ cap = cv2.VideoCapture(sys.argv[1])
+ if not cap.isOpened():
+ cap = cv2.VideoCapture(int(sys.argv[1]))
+
+ if not cap.isOpened():
+ print 'Cannot initialize video capture'
+ sys.exit(-1)
+
+ data_matrix_demo(cap)