<>0. Operation effect
<> Complete steps
<>1. Picture preparation and import
To make an album, enough pictures are essential , Otherwise, there is only one picture in the whole album. How boring it is to repeat back and forth , So we need a folder for pictures , To facilitate import , It's all here jpg format :
Picture import code :
path='.\album\';% Folder path files=dir(fullfile(path,'*.jpg')); picNum=size(files,1);
% Traverse each image under the path for i=1:picNum fileName = strcat(path,files(i).name); img = imread(
fileName); imgSet.(['p',num2str(i)])=img; end
<>2. Make a mask layer for each picture
for i=1:length(BlockNum)% Number of ring layers blockNum=BlockNum(i);% Number of pictures per layer Rrange=R(i,:);%
Radius range of one layer at a time for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(
disMesh>Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*
pi/blockNum))&(thetaMesh<(j*2*pi/blockNum)); end end
The fan-shaped structure is constructed by superposition of two judgment conditions :
* The radius from the center point is [r,R] Range
* And x The included angle of the positive half shaft of the shaft is at [theta1,theta2] between
This is a process of taking intersection , The picture description is about the following :
Suppose we have built Xmesh,Ymesh matrix
[XMesh,YMesh]=meshgrid(-1200:1:1200,-1200:1:1200);
Distance matrix :
Then the distance matrix disMesh It can be constructed like this :
disMesh=sqrt(XMesh.^2+YMesh.^2);
theta Angular matrix :
We can certainly think of it first atan2, A four quadrant anti sinusoidal function , His mapping relationship is like this :
Is from z The value range is -pi reach pi, And so x The negative half axis is 0 Angular , Here we will z Value increase pi And flip the axis , Can get theta Angular matrix :
thetaMesh=atan2(YMesh,XMesh)+pi; thetaMesh=thetaMesh(:,end:-1:1);
After the change is from x Shaft positive half shaft start , Mapping range is [0,2*pi].
<>3. Resize each chart
We found every mask x,y Cut it out of the range :
Then, the size of the original image is transformed to at least one side length equal to the mask according to the scale , The other side is longer than the mask , Then intercept the center of the picture , The code is as follows :
for i=1:length(BlockNum)% Number of ring layers blockNum=BlockNum(i);% Number of pictures per layer Rrange=R(i,:);%
Radius range of each layer for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(
disMesh>Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*
pi/blockNum))&(thetaMesh<(j*2*pi/blockNum)); TrueX=find(sum(tempBoard,1)>0);
TrueY=find(sum(tempBoard,2)>0); tempMask=tempBoard(min(TrueY):max(TrueY),min(
TrueX):max(TrueX)); x1=YMesh(min(TrueX),min(TrueY)); y1=XMesh(min(TrueX),min(
TrueY)); x2=YMesh(max(TrueX),max(TrueY)); y2=XMesh(max(TrueX),max(TrueY)); xdiff
=x2-x1; ydiff=y2-y1; pic=imgSet.(['p',num2str(tempPic)]); [rows,cols,~]=size(pic
); ratio=[ydiff+1,xdiff+1]./[rows,cols]; newsize=ceil([rows,cols].*max(ratio));
offset=floor((newsize-[ydiff+1,xdiff+1])./2); pic=imresize(pic,newsize); pic=pic
((1:ydiff+1)+offset(1),(1:xdiff+1)+offset(2),:); end end
<>3. Detailed explanation of drawing and drawing parameters
Basic parameters :
BlockNum=[7,11];% Number of sectors per floor
R=[300,670;% Radius range of the first floor
670,1090];% Radius range of the second layer
lineColor=[0.98,0.98,0.98]; Line color
lineWidth=2;% Line thickness
We'll talk about the properties of the line later
Drawing is directly used image function , There's nothing to say about this , If there are not many pictures in the folder, we will use the remainder method to cycle the previous pictures :
tempPic=1; for i=1:length(BlockNum) blockNum=BlockNum(i); for j=1:blockNum
tempPic=tempPic+1; tempPic=mod(tempPic-1,picNum)+1; end end
We find that the edge aliasing is more serious when drawing directly :
It's easy for us to think of drawing lines to hide our ugliness :
t=0:0.001:(2*pi+0.001); for i=1:length(BlockNum) blockNum=BlockNum(i); Rrange=R
(i,:); for j=1:blockNum plot(cos(j*2*pi/blockNum).*Rrange,sin(j*2*pi/blockNum).*
Rrange,'Color',lineColor,'LineWidth',lineWidth) end plot(cos(t).*Rrange(1),sin(t
).*Rrange(1),'Color',lineColor,'LineWidth',lineWidth) plot(cos(t).*Rrange(2),sin
(t).*Rrange(2),'Color',lineColor,'LineWidth',lineWidth) end
Of course, you can also draw a black line :
It only needs lineColor=[0,0,0] perhaps lineColor='k’ that will do
<>4. Complete code
function ringAlbum BlockNum=[7,11]; R=[300,670; 670,1090]; lineColor=[0.98,0.98
,0.98]; lineWidth=2; path='.\album\';% Folder name files=dir(fullfile(path,'*.jpg'));
picNum=size(files,1); % Traverse each image under the path for i=1:picNum fileName = strcat(path,files(i)
.name); img = imread(fileName); imgSet.(['p',num2str(i)])=img; end fig=figure(
'units','pixels',... 'position',[20 60 560 560],... 'Color',[1 1 1]); ax=axes(
'Units','pixels',... 'parent',fig,... 'Color',[1 1 1],... 'Position',[0 0 560,
560],... 'XLim',[-1200,1200],... 'YLim',[-1200,1200],... 'XColor','none',...
'YColor','none'); hold(ax,'on') ax.YDir='reverse'; ax.XDir='normal'; [XMesh,
YMesh]=meshgrid(-1200:1:1200,-1200:1:1200); disMesh=sqrt(XMesh.^2+YMesh.^2);
thetaMesh=atan2(YMesh,XMesh)+pi; thetaMesh=thetaMesh(:,end:-1:1); tempPic=1; t=0
:0.001:(2*pi+0.001); for i=1:length(BlockNum) blockNum=BlockNum(i); Rrange=R(i,:
); for j=1:blockNum tempBoard=ones(2401,2401)==1; tempBoard=tempBoard&(disMesh>
Rrange(1))&(disMesh<Rrange(2)); tempBoard=tempBoard&(thetaMesh>((j-1)*2*pi/
blockNum))&(thetaMesh<(j*2*pi/blockNum)); TrueX=find(sum(tempBoard,1)>0); TrueY=
find(sum(tempBoard,2)>0); tempMask=tempBoard(min(TrueY):max(TrueY),min(TrueX):
max(TrueX)); x1=YMesh(min(TrueX),min(TrueY)); y1=XMesh(min(TrueX),min(TrueY));
x2=YMesh(max(TrueX),max(TrueY)); y2=XMesh(max(TrueX),max(TrueY)); xdiff=x2-x1;
ydiff=y2-y1; pic=imgSet.(['p',num2str(tempPic)]); [rows,cols,~]=size(pic); ratio
=[ydiff+1,xdiff+1]./[rows,cols]; newsize=ceil([rows,cols].*max(ratio)); offset=
floor((newsize-[ydiff+1,xdiff+1])./2); pic=imresize(pic,newsize); pic=pic((1:
ydiff+1)+offset(1),(1:xdiff+1)+offset(2),:); image(ax,[x1,x2],[y1,y2],pic,
'alphaData',tempMask); tempPic=tempPic+1; tempPic=mod(tempPic-1,picNum)+1; end
for j=1:blockNum plot(cos(j*2*pi/blockNum).*Rrange,sin(j*2*pi/blockNum).*Rrange,
'Color',lineColor,'LineWidth',lineWidth) end plot(cos(t).*Rrange(1),sin(t).*
Rrange(1),'Color',lineColor,'LineWidth',lineWidth) plot(cos(t).*Rrange(2),sin(t)
.*Rrange(2),'Color',lineColor,'LineWidth',lineWidth) end end
Technology