一个简单有趣的小问题,枫叶嵌套问题的完美解决
生活随笔
收集整理的這篇文章主要介紹了
一个简单有趣的小问题,枫叶嵌套问题的完美解决
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文末更了個法二
前兩天看到一個很有意思的小問題,描述如下:
思路也非常簡單,我們首先檢測楓葉中心,并用楓葉旋轉來代替反方向的框旋轉,獲取旋轉角 ttt 在 [0,pi/2][0,pi/2][0,pi/2] 區間內,豎直高度變化和橫向寬度變化,我們可以將這兩個變化看作是連續的,因而我們只需要檢測兩個函數是否有交點即可,即是否:
?t0,fx(t0)?fy(t0)=0{\exists}t_0,f_x(t_0)-f_y(t_0)=0 ?t0?,fx?(t0?)?fy?(t0?)=0
由于我們很難獲得這兩個函數,實際上對于fx(t)?fy(t)f_x(t)-f_y(t)fx?(t)?fy?(t),我們能得到的只有數組形式,因而我們只需要檢測有沒有相鄰兩個數相乘后數值<=0即可。
代碼也不難實現,如下為含注釋的完整代碼:
function mapleInSquaremaplePic=imread('test3.png'); %讀取圖片 maplePic=rgb2gray(maplePic); %灰度化 boolPic=double(maplePic)<200; %確定楓葉區域 [RowSet,ColSet]=find(boolPic);%楓葉區域像素點坐標%去中心化 RowCenter=(min(RowSet)+max(RowSet))/2; ColCenter=(min(ColSet)+max(ColSet))/2; RowSet=RowSet-RowCenter; ColSet=ColSet-ColCenter;pieceNum=200; %角度細化數目 thetaSet=linspace(0,pi/2,pieceNum);%將角度細化%初始化 rowDiff=zeros(1,pieceNum); colDiff=zeros(1,pieceNum);for i=1:pieceNumtheta=thetaSet(i);%像素點旋轉tempRowSet=cos(theta).*RowSet-sin(theta).*ColSet;tempColSet=cos(theta).*ColSet+sin(theta).*RowSet;%記錄長度rowDiff(i)=max(tempRowSet)-min(tempRowSet);colDiff(i)=max(tempColSet)-min(tempColSet); end%圖像顯示:有交點說明有符合題意角度 figure(1) hold on plot(1:pieceNum,rowDiff,'LineWidth',1) plot(1:pieceNum,colDiff,'LineWidth',1)%做差后左右比較,檢測f1(x)-f2(x)是否有零點,零點位置 diffData=rowDiff-colDiff; multData=diffData(1:end-1).*diffData(2:end); crossPos=find(multData<=0);%如果存在交點 if ~isempty(crossPos)%角度及邊長矩陣theta_edge_mat=zeros(length(crossPos),2);for i=1:length(crossPos)crossTheta=(thetaSet(crossPos(i))+thetaSet(crossPos(i)+1))/2;%旋轉角度theta_edge_mat(i,1)=crossTheta;%像素點旋轉tempRowSet=cos(crossTheta).*RowSet-sin(crossTheta).*ColSet;tempColSet=cos(crossTheta).*ColSet+sin(crossTheta).*RowSet;%獲取范圍信息rowRange=[min(tempRowSet),max(tempRowSet)];colRange=[min(tempColSet),max(tempColSet)];theta_edge_mat(i,2)=(rowRange(2)-rowRange(1)+colRange(2)-colRange(1))/2;%獲取旋轉后的點集pntSet=[rowRange(1),colRange(1);rowRange(1),colRange(2);rowRange(2),colRange(1);rowRange(2),colRange(2)];%旋轉回去newPntSet(:,1)=cos(-crossTheta).*pntSet(:,1)-sin(-crossTheta).*pntSet(:,2)+RowCenter;newPntSet(:,2)=cos(-crossTheta).*pntSet(:,2)+sin(-crossTheta).*pntSet(:,1)+ColCenter;%繪圖figure(i+1)imshow(maplePic)hold onplot(newPntSet([1 2],2),newPntSet([1 2],1),'r','LineWidth',1)plot(newPntSet([2 4],2),newPntSet([2 4],1),'r','LineWidth',1)plot(newPntSet([1 3],2),newPntSet([1 3],1),'r','LineWidth',1)plot(newPntSet([4 3],2),newPntSet([4 3],1),'r','LineWidth',1)end end %結果輸出 disp(theta_edge_mat)end由于我沒有下載題目數據哈,于是自己找了幾張圖試了試,效果還不錯:
示例一:
旋轉角及邊長
0.8485 350.8903
示例二:
旋轉角及邊長
0.1066 626.1161
示例三(多個正方形符合情況):
實際上是將實例一葉柄截短了點,讓他更方了:
旋轉角及邊長
0.1223 325.3239
0.3197 332.4445
1.1248 342.3447
方法二:轉矩形
只給代碼:
function mapleInSquare2 maplePic=imread('test.png'); % 讀取圖片 maplePic=rgb2gray(maplePic); % 灰度化 boolPic=double(maplePic)<200; % 確定楓葉區域 [RowSet,ColSet]=find(boolPic);% 楓葉區域像素點坐標% 去中心化 RowCenter=(min(RowSet)+max(RowSet))/2; ColCenter=(min(ColSet)+max(ColSet))/2; RowSet=RowSet-RowCenter; ColSet=ColSet-ColCenter;% 將角度細化 pieceNum=200; thetaSet=linspace(0,pi/2,pieceNum);% 初始化 L1Set=zeros(1,pieceNum); L2Set=zeros(1,pieceNum);for i=1:pieceNumtheta=thetaSet(i);% 向量內積L1=cos(theta).*RowSet+sin(theta).*ColSet;L2=cos(theta+pi/2).*RowSet+sin(theta+pi/2).*ColSet;L1Set(i)=max(L1)-min(L1);L2Set(i)=max(L2)-min(L2); end%圖像顯示:有交點說明有符合題意角度 figure(1) hold on plot(1:pieceNum,L1Set,'LineWidth',1) plot(1:pieceNum,L2Set,'LineWidth',1)%做差后左右比較,檢測f1(x)-f2(x)是否有零點,零點位置 diffData=L1Set-L2Set; multData=diffData(1:end-1).*diffData(2:end); crossPos=find(multData<=0);%如果存在交點 if ~isempty(crossPos)%角度及邊長矩陣theta_edge_mat=zeros(length(crossPos),2);for i=1:length(crossPos)% 旋轉角度及長度均值theta_edge_mat(i,1)=(thetaSet(crossPos(i))+thetaSet(crossPos(i)+1))/2;L1=cos(theta_edge_mat(i,1)).*RowSet+sin(theta_edge_mat(i,1)).*ColSet;L2=cos(theta_edge_mat(i,1)+pi/2).*RowSet+sin(theta_edge_mat(i,1)+pi/2).*ColSet;theta_edge_mat(i,2)=(max(L1)-min(L1)+max(L2)-min(L2))/2;tmeanRow=cos(theta_edge_mat(i,1))*(max(L1)+min(L1))/2+cos(theta_edge_mat(i,1)+pi/2)*(max(L2)+min(L2))/2;tmeanCol=sin(theta_edge_mat(i,1))*(max(L1)+min(L1))/2+sin(theta_edge_mat(i,1)+pi/2)*(max(L2)+min(L2))/2;% 構造正方形四個頂點newPntSet(:,1)=cos((pi/4:pi/2:2*pi)+theta_edge_mat(i,1))'.*sqrt(2)./2.*theta_edge_mat(i,2)+tmeanRow+RowCenter;newPntSet(:,2)=sin((pi/4:pi/2:2*pi)+theta_edge_mat(i,1))'.*sqrt(2)./2.*theta_edge_mat(i,2)+tmeanCol+ColCenter;%繪圖figure(i+1)imshow(maplePic)hold onplot(newPntSet([1 2],2),newPntSet([1 2],1),'r','LineWidth',1)plot(newPntSet([2 3],2),newPntSet([2 3],1),'r','LineWidth',1)plot(newPntSet([3 4],2),newPntSet([3 4],1),'r','LineWidth',1)plot(newPntSet([1 4],2),newPntSet([1 4],1),'r','LineWidth',1)end end %結果輸出 disp(theta_edge_mat) end算出結果長度與法一相同,不過計算出的角度值是互余的(相加等于90度)
總結
以上是生活随笔為你收集整理的一个简单有趣的小问题,枫叶嵌套问题的完美解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hash算法详解
- 下一篇: 显示器色彩精度测试软件,色彩还原精准度测