这段时间老师交给我们一个任务,将一个扇形图像转换为矩形图像。因为是第一次接触数字图像处理,感觉自己磕磕碰碰地从毫无头绪到基本完成要求,还是挺舒心的,所以在这记录一下,也希望可以帮助到看到这篇文章的人。本人小萌新,有错误请指正~
本次实现基于matlab,使用的时最近邻插值法。
目的:将扇形图像转换为矩形图像
实现原理:
(使用到的函数和代码中定义的参数都用()在下文给写出来了。)
假定我们读入(imread)的是左边的这样一个扇形,那么要将它转换为右边那样的矩形。
先把传入的扇形倒置(flip),绿色记为内半径(Lstart),蓝色记为外半径,黄色为扇形角度(alpha*2)。
那么,要把这个扇形转换为矩形,我们把外半径作为矩形的长hOut,矩形的宽wOut可以自己定(本次实现代码将长定为和宽相等,即得到一个正方形)。
接下来要做一件事就是将扇形的角度均分,扇形角度(alpha*2)/矩形的宽wOut
这样,从[1,wOut]中,每一个值都对应了一个角度。以本例子代码里面的图像,扇形角度是30°,假设我们的宽wOut定位20,那么当wOut等于10时,对应的就是15°,如下图
我们要得到的就是这个角度对应的黄线上的像素数据,然后再将这些数据赋给矩形上对应的位置。
那我们要怎么确认这个角度上这条黄线的像素对应到矩形上的像素它的坐标位置在哪呢?容易看出,这条黄线是在15°时取的,那么它投影到矩形中就在矩形宽等于10的位置上(如上图右所示)。
所以,每当宽wOut取一个值,都会有一个对应的角度,在扇形中这个角度线段的像素投影到矩形中去,当区间所有[1,wOut]里的值都进行一次这样的映射,那么我们就的到了一幅矩形图像。
得到矩形图像后,再将它倒置(flip)就可以得到一个正置的矩形图像。
代码示例:
%% 参数说明
% hIn 输入图像的横数
% wIn 输入图像的列数
% ratio 比例(要求小于1),用于确定输出图像的高度(输出图像的横数)
% 比例是 外半径/全半径
% 比例越小,输出的图像底部空出的内容越多
% hOut 输出图像的横数
% wOut 输出图像的列数
% Lstart 内半径
% Llength内半径+外半径
% angle 张角的一半(单位是°)
% alpha 张角矩阵
% lats 输出图像的横像素矩阵
% lons 输出图像的列像素矩阵
%% 读取输入图像数据
imIn=imread('test_cy.jpg');
imIn=flip(imIn); % 倒置读入图像数据
imshow(imIn)
[hIn,wIn,~]=size(imIn);
%% 根据扇形几何关系计算输出图像像素
angle=15; % 张开角度的一半
ratio=8/11; % 比例要求<1
hOut=ceil(hIn*ratio); % 输出图像的行数,取整操作
Lstart=hIn-hOut; % hIn-hOut (输入图像的行数减去输出图像的行数,得到内半径)
% 不严格来说,这个值就是“输入的图像底部空出的长度”
Llength=hIn; % 等于输入图像行数
wOut=hOut; % 输出图像列数
imOut=zeros(hOut,wOut,3); % 根据大小分配输出图像数据空间
%% 根据张开角度范围划分射线角度
alpha=linspace(-angle,angle,wOut);
%% 遍历输入图像数据中每个角度射线上的像素,找到并找到对应的输出图像数据中的像素坐标位置,进行赋值
figure(1) %定位图像
set(gcf,'name','扇形定位点')
xlim([0,wIn])
ylim([0,hIn])
axis equal
i=1;
for i=1:wOut %遍历输入图像数据中每个角度射线上的像素
d=cosd(alpha(i))*(Lstart:hIn); %对应的输出图像矩阵纵坐标矩阵
lats=ceil(d); %对d向上取整
b=sind(alpha(i))*(Lstart:hIn)+wIn/2; %对应的输出图像矩阵横坐标矩阵
lons=ceil(b); %对b向上取整
for j=1:hOut
imOut(j,i,:)=imIn(lats(j),lons(j),:);%扇形的每个角度射线上的像素对应到矩形中,使用最近邻插值
%由于扇形变换到矩形后面积增大,所以变换后的图像清晰度下降
end
plot(lons,lats) %画出经纬度坐标
axis equal
hold on
end
%%
imOut=uint8(imOut);
figure(2) %矩形图像输出
set(gcf,'name','输出图像')
imOut=flip(imOut);
imshow(imOut)
axis equal
figure(3) %输入图像
set (gcf,'name','输入图像')
imIn=flip(imIn);
imshow(imIn)
axis equal
%% 保存矩形图像
imwrite(imOut,'test_cy_ju_1.jpg')
本代码局限性:
- 需要事先确定内圆半径和外圆半径(或比率)
- 圆心一定要紧贴输入图像的顶部中间位置。
- 需要事先确认扇形夹角
本代码参考了博主井底之蛤 发布的关于矩形转换为扇形的算法文章 ,在此表示感谢。https://blog.csdn.net/JISANSAN/article/details/119293707
若想要制作进行测试的扇形图像,可以使用上面博主文章中的代码进行生成。
下面给出的压缩包,里面包含了我写好的代码,用于制作扇形的矩形,用于测试的扇形,变换得到的矩形。