文章目录
安装
- python
pip install opencv-python
类型转换
Mat和IpIImage* 之间的互转
IplImage* img;
Mat test = cv::cvarrToMat(img);
彩色图转灰度图
Mat my_bgr = imread(...);// 读自己的影像
Mat my_grey;
cv::cvtColor(my_bgr, my_grey, cv::COLOR_BGR2GRAY);
BGR转YUV并分割三通道
//inImage为输入的RGB图像
cv::Mat imageY(inImage.rows,inImage.cols,1);
cv::Mat imageU(inImage.rows,inImage.cols,1);
cv::Mat imageV(inImage.rows,inImage.cols,1);
cv::Mat imageYUV;
cv::cvtColor(inImage,imageYUV,CV_BGR2YUV);
std::vector<Mat> mv;
split(inImage, (vector<Mat>&)mv);
imageY = mv[0].clone();
imageU = mv[1].clone();
imageV = mv[2].clone();
常用矩阵生成
生成全0,全1矩阵
Mat tmpdata0 = Mat::zeros(rows, cols, CV_8UC1);//rows行cols列的全0矩阵
Mat tmpdata1 = Mat::ones(rows, cols, CV_8UC1);//rows行cols列的全0矩阵
// 应用之一:将mat中所有的数值初始化为一个特定的值,比如72
Mat tmpdata72 = 72* Mat::ones(rows, cols, CV_8UC1);
取值以及取ROI
取值
- 浮点取值(i,j处):
float* ptr_Affinity = Affinity_matrix.ptr<float>(i);
ptr_Affinity[j]
- uchar取值(i,j处):
uchar* ptr_Affinity = Affinity_matrix.ptr<uchar>(i);
ptr_Affinity[j]
取矩阵的roi
规则矩形的roi
int x=280; // 裁剪区域起始点 x坐标
int y=400; // 裁剪区域起始点 y坐标
int width=100; // 裁剪区域宽度
int height=100; // 裁剪区域高度
Rect area(x, y, width, height);
Mat guide_roi = guide(area);
不规则四边形
读取txt, 转为浮点型的mat
void txt2Mat32F(fstream &txtfile, int rows, int cols, Mat &target) {
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
txtfile >> target.at<float>(i, j);
}
}
return;
}
滤波
高斯滤波
- python:
API:cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
使用:img_gauss = cv.GaussianBlur(img, (3, 3), 1)
膨胀
Mat structure_element = getStructuringElement(MORPH_RECT, Size(3, 3)); //设置膨胀/腐蚀的核为矩形,大小为3*3
dilate(target_roi, target_roi_dilate, structure_element); //膨胀
视差后处理的opencv函数
https://docs.opencv.org/master/da/d17/group__ximgproc__filters.html
1. DT滤波 (domain filter)
头文件:
#include <opencv2/ximgproc/edge_filter.hpp>
调用示例:
double sigmaSpatial = 0.2;
double sigmaColor = 0.1;
cv::Ptr<cv::ximgproc::DTFilter> dtf = cv::ximgproc::createDTFilter(guideImg, sigmaSpatial, sigmaColor, cv::ximgproc::DTF_NC,3);
dtf->filter(src, dst, -1);
//cv::ximgproc::dtFilter(guideImg, src, dst, sigmaSpatial, sigmaColor, cv::ximgproc::DTF_NC, 3);
cv::namedWindow("Domain Transform Filter");
imshow("Domain Transform Filter", dst);
waitKey(0);
}
变换
仿射变换
数学表达
一个仿射变换对应着一个矩阵和一个向量的加法,具体来说,表现为在向量空间中对向量乘以一个矩阵再加上一个向量,数学形式可以表现为
A
,
B
A,B
A,B的形式也可以表现为
M
M
M的形式,具体为:
A
=
[
a
00
a
01
a
10
a
11
]
2
×
2
B
=
[
b
00
b
10
]
2
×
1
M
=
[
A
B
]
=
[
a
00
a
01
b
00
a
10
a
11
b
10
]
2
×
3
\begin{array}{l} A=\left[\begin{array}{ll} a_{00} & a_{01} \\ a_{10} & a_{11} \end{array}\right]_{2 \times 2} \quad B=\left[\begin{array}{l} b_{00} \\ b_{10} \end{array}\right]_{2 \times 1} \\ \\ \\ M=\left[\begin{array}{ll} A & B \end{array}\right]=\left[\begin{array}{lll} a_{00} & a_{01} & b_{00} \\ a_{10} & a_{11} & b_{10} \end{array}\right]_{2 \times 3} \end{array}
A=[a00a10a01a11]2×2B=[b00b10]2×1M=[AB]=[a00a10a01a11b00b10]2×3
仿射变换考虑的是图图之间的关系,先假设左图上某一点的坐标为:
X
=
[
x
y
]
\mathrm{X}=\left[\begin{array}{l} \mathrm{x} \\ \mathrm{y} \end{array}\right]
X=[xy]
对其进行仿射变换,则表示为:
T
=
A
⋅
[
x
y
]
+
B
T
=
M
⋅
[
x
,
y
,
1
]
T
\begin{aligned} &\mathrm{T}=A \cdot\left[\begin{array}{l} \mathrm{x} \\ \mathrm{y} \end{array}\right]+\mathrm{B} \\ &\mathrm{T} =\mathrm{M} \cdot[\mathrm{x}, \mathrm{y}, 1]^{\mathrm{T}}\\ \end{aligned}
T=A⋅[xy]+BT=M⋅[x,y,1]T
进一步地,仿射变换后的结果为:
T
=
[
a
00
x
+
a
01
y
+
b
00
a
10
x
+
a
11
y
+
b
10
]
T=\left[\begin{array}{l} a_{00} x+a_{01} y+b_{00} \\ a_{10} x+a_{11} y+b_{10} \end{array}\right]
T=[a00x+a01y+b00a10x+a11y+b10]
通常,我们知道两幅图上不共线的三对点,就可以根据这三对点,求解矩阵 M M M。即相当于已知 T T T与 X X X,求解 M M M。
opencv中的求解函数
warpAffine
函数。
void cv::warpAffine (
InputArray src, // 输入图像
OutputArray dst, // 输出图像,尺寸由dsize指定
InputArray M, // 2*3的变换矩阵,见上数学表达
Size dsize, // 指定输出图像大小
int flags = INTER_LINEAR, //插值标志位,如果要实现反变换,使用WARP_INVERSE_MAP
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
其中,关于flags,如果为反变换WARP_INVERSE_MAP,则有:
dst
(
x
,
y
)
=
src
(
M
11
x
+
M
12
y
+
M
13
,
M
21
x
+
M
22
y
+
M
23
)
\operatorname{dst}(x, y)=\operatorname{src}\left(M_{11} x+M_{12} y+M_{13}, M_{21} x+M_{22} y+M_{23}\right)
dst(x,y)=src(M11x+M12y+M13,M21x+M22y+M23)
正反变换的示例代码:
//创建仿射变换目标图像与原图像尺寸类型相同
warp_dstImage = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());
//设置三个点来计算仿射变换
srcTri[0] = Point2f(0, 0);
srcTri[1] = Point2f(srcImage.cols - 1, 0);
srcTri[2] = Point2f(0, srcImage.rows - 1);
dstTri[0] = Point2f(srcImage.cols * 0.0, srcImage.rows * 0.33);
dstTri[1] = Point2f(srcImage.cols * 0.85, srcImage.rows * 0.25);
dstTri[2] = Point2f(srcImage.cols * 0.15, srcImage.rows * 0.7);
//计算仿射变换矩阵
warp_mat = getAffineTransform(srcTri, dstTri);
//对加载图形进行仿射变换操作
warpAffine(srcImage, warp_dstImage, warp_mat, warp_dstImage.size());
//显示仿射变换结果
String warp_windowName = "仿射变换";
namedWindow(warp_windowName, WINDOW_AUTOSIZE);
imshow(warp_windowName, warp_dstImage);
// 尝试仿射逆变换是否可以变换回去
Mat srcImage_from_dst = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());
warpAffine(warp_dstImage, srcImage_from_dst,warp_mat, srcImage_from_dst.size(), WARP_INVERSE_MAP);
String warp_windowName_2 = "逆仿射变换";
namedWindow(warp_windowName_2, WINDOW_AUTOSIZE);
imshow(warp_windowName_2, srcImage_from_dst);