sortRectPoint()
这个函数,主要是将图片中的最近外接矩形的顶点坐标和解码后获得的data matrix顶点坐标的四个顶点对应上,并且按照顺时针存放。
void PosGuide::sortRectPoint(vector<Point2f> _dmTranPoints, //二维码解码后获得的data matrix最外侧矩形顶点坐标
Mat _warpMat, //矫正图片时的仿射变换矩阵
vector<Point2f>& _dmRectPoints) //当前提取的最接近图片中心点矩形,即二维码的矩形顶点坐标
1.1 opencv中Mat的成员colRange()和rowRange()
colRange() && rowRange()分别是截取矩阵的列和矩阵的行。如下所式:
Mat rowRange(int startrow, int endrow) const;
Mat colRange(int startcol, int endcol) const;
注意截取的行或者列式是从 startrow 到 endrow 或者 startcol 到 endcol,并且 endrow && endrow 是取不到的,矩阵是从0开始的,不是1!!!
举个栗子:
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <sys/time.h>
#include <windows.h>
using namespace std;
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
void display_mat(Mat mat, string str)
{
cout << "======" << str << "======" << endl;
for(int i = 0; i < mat.rows; i++)
{
for(int j = 0; j < mat.cols; j++)
{
cout << mat.at<int>(i,j);
}
cout << endl;
}
cout << endl;
}
void test_mat()
{
Mat example = (Mat_<int>(3,3)<<1,2,3,4,5,6,7,8,9);
Mat temp_row1 = example.rowRange(1,2); //从第2行开始,截取到第3行结束,但是第3行不保存
Mat temp_row2 = example.rowRange(Range(1,3)); //从第2行开始,截取到第4行结束(超过矩阵的维度,不报错),保存矩阵第2,3两行
Mat temp_col1 = example.colRange(0,2); //从第1列开始截取,截到第3列结束,但是第3列不保存
Mat temp_col2 = example.colRange(0,3); //从第1列开始截取,截到第4列结束(超过矩阵的维度,不报错),保存矩阵第1,2,3行
//打印这些截取的矩阵,以验证想法。
display_mat(example, "example");
display_mat(temp_row1, "temp_row1");
display_mat(temp_row2, "temp_row2");
display_mat(temp_col1, "temp_col1");
display_mat(temp_col2, "temp_col2");
}
int main()
{
// do_it();
test_mat();
return 0;
}
执行结果:
1.2 opencv中Mat的rol() && col()
和4.1节中的colRange() && rowRange()不同,row() 和 col() 是得到特定的 行 或者 列
举个栗子:
Mat temp_col3 = example.col(2);
display_mat(temp_col3, "temp_col3");
执行结果:
1.3 由已知的data matrix顶点坐标,和仿射矩阵,反算实际顶点坐标
由以下公式可知
(1) M = [ A C ] = [ a 00 a 01 b 00 a 10 a 11 b 10 ] M=\left[ \begin{matrix} A & C\end{matrix}\right]=\left[ \begin{matrix} a_{00} & a_{01} & b_{00} \\ a_{10} &a_{11} & b_{10}\end{matrix}\right] \tag{1} M=[AC]=[a00a10a01a11b00b10](1)
(2) T = A ∗ [ x y ] + C = M ∗ [ x y 1 ] T= A * \left[ \begin{matrix} x \\ y\end{matrix}\right]+C=M*\left[\begin{matrix}x\\y\\1 \end{matrix}\right] \tag{2} T=A∗[xy]+C=M∗⎣⎡xy1⎦⎤(2)
A = M . c o l R a n g e ( 0 , 2 ) , C = M . c o l ( 2 ) A = M.colRange(0,2),C=M.col(2) A=M.colRange(0,2),C=M.col(2)
(3) [ x y ] = A − 1 T − A − 1 C \left[ \begin{matrix}x \\ y \end{matrix}\right] = A^{-1}T-A^{-1}C \tag{3} [xy]=A−1T−A−1C(3)
通过这个公式(3),反算出原始的data matrix的矩形顶点坐标。
1.4 vector中的reserve()
给向量预留空间,因为创建时不确定向量的大小,所以使用reserve()预留空间,这样可以避免使用push_back()添加到vector中,可以直接使用等号。