opencv 常用操作小记(C++/Python)

3 篇文章 0 订阅

安装

  • 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);

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FLOWVERSE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值