Opencv之极坐标对图像进行变换

Opencv之极坐标对图像进行变换,第1张

学习资料参考:

张平.《OpenCV算法精解:基于Python与C++》.[Z].北京.电子工业出版社.2017.


浅析原理

与使用二维函数进行表示输入图像的像素一致,此处采用利用极坐标与笛卡尔坐标的一一对应关系得到图像输出矩阵的每一个像素值。




实现
#include
#include
#include
using namespace cv;
Mat polar(Mat I, Point2f center, Size size, float minr = 0, float mintheta = 0, float thetaStep = 1.0 / 4, float rStep = 1.0) {
	//构造全0矩阵,此处为列矩阵(可看作一条从中心点发出的射线的每一点r取值)
	Mat ri = Mat::zeros(Size(1, size.height), CV_32FC1);
	//列矩阵赋值为每个坐标点的r值
	for (int i = 0; i < size.height; ++i) {
		ri.at<float>(i, 0) = minr + i * rStep;
	}
	//由于宽度为150,那么将该列向量在x轴方向进行复制1440(360*4)次,即将输出图像的所有r值确定
	Mat r = repeat(ri, 1, size.width);
	//构建theta,此处构建的是行向量矩阵(可看作一个圆环的\theta取值范围)
	Mat thetaj = Mat::zeros(Size(size.width, 1), CV_32FC1);
	//行向量赋值为每个坐标点的\theta取值
	for (int j = 0; j < size.width; ++j) {
		thetaj.at<float>(0, j) = mintheta + j * thetaStep;
	}
	//在y轴方向进行复制150次
	Mat theta = repeat(thetaj, size.height, 1);
	//将极坐标转换为笛卡尔坐标
	Mat x, y;
	polarToCart(r, theta, x, y, true);
	//将坐标原点移动到中心点
	x += center.x;
	y += center.y;
	//最邻近插值
	Mat dst = 125 * Mat::ones(size, CV_8UC1);
	for (int i = 0; i < size.height; ++i) {
		for (int j = 0; j < size.width; ++j) {
			float xij = x.at<float>(i, j);
			float yij = y.at<float>(i, j);
			int neareastx = int(round(xij));
			int neareasty = int(round(yij));
			if ((0 <= neareastx && neareastx < I.cols) && (0 <= neareasty && neareasty < I.rows))
				dst.at<uchar>(i, j) = I.at<uchar>(neareasty, neareastx);
		}
	}
	return dst;
}
int main() {
	//读取图片
	Mat I = imread("p4.jpg", IMREAD_GRAYSCALE);
	if (!I.data)
		return -1;
	//极坐标变换
	float thetaStep = 1.0 / 4;
	//设置距离中心的最短距离
	float minr = 163;
	//设置输出图片的大小或者需要处理的圆环的大小
	//第一个参数为宽度,第二个参数为高度
	Size size(int(360 / thetaStep), 150);
	//进行圆环处理
	Mat dst = polar(I, Point2f(313, 313), size, minr);
	//沿水平方向的镜像处理
	flip(dst, dst, 0);
	//显示结果
	imshow("I", I);
	imshow("极坐标变换", dst);
	waitKey(0);
	return 0;
}

运行结果

原图

极坐标变换后的结果


注意:由于代码中的特定参数与图像的有关,此处解释以下我的参数设计:

float minr = 163;
Size size(int(360 / thetaStep), 150);
Mat dst = polar(I, Point2f(313, 313), size, minr);

minr代表章的外围字符距离章的中心的最短距离。



size(,150)该150为章印的字符的宽度。



Point2f(313, 313)为章印的中心坐标。



原图为616x616大小


但上述图片转换的并不美观,我们发现并不一定要360度,其实270度就够了,那么将度数的最小值设为-230即可,得到如下显示:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/568497.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存