前言
有時候為了將一張圖片以3維的形式顯示出來,可以采用matlab的強大繪圖功能。這里的3維其中的兩維當然就是圖片的xy坐標了,第3維就是圖片中對應坐標點的像素值。例如,在c/c++編程時有可能會遇到生成了一張跟概率密度相關的圖片,現在需要將其可視化,看它到底長什么樣,這時候就需要用到這個功能。本節就簡單實現一下這個。
開發環境:matlab2012a
實驗基礎
可以使用mesh函數實現,mesh函數是用來畫曲面的網格表面的。
也可以使用surfl函數來實現,surfl是用來畫光滑的曲面的。
有時候在matlab編程時會出現如下錯誤:
即:Subscript indices must either be real positive integers or logicals.
因為matlab中的下標是從1開始的,不是從0開始的,這點和c/c++完全不同。
Matlab知識點總結:
如果對圖片image取一個矩形范圍的話,那么應該是先取列的范圍,比如image([a b c d]),其中的a和b是列的范圍,c和d是行的范圍。
用meshgrid來指定x和y的坐標范圍時,先指定的是行的范圍,然后才是列的范圍,比如說meshgrid([a:b, c:d]),其中x軸的范圍是a到b,y軸范圍是c到d。
實驗結果
本次實驗是給定一張圖片,該圖片中每個像素點值的類型為長整型,首先將該圖片轉換成每個像素值為0~1的值的圖片,轉換的根據是求出每個像素點值的概率大小,即轉換后的圖片是一張2維概率分布圖。最后分別用mesh函數和surfl函數將該概率圖顯示出來。當然因為這些圖片來自人體皮膚的CrCb分布,所以CrCb的值只在一定范圍內才有,所以顯示的時候只顯示其中的一部分,且密度大小顯示是從0到最大密度處,並不是0~1。
原始2維圖如下:
從這幅圖可以發現,其實看不到什么內容,因為像素值的類型為長整型,而里面的值相對長整型最大值來說又太小了,所以看起來比較黑。
mesh函數繪制后的結果如下:
surfl函數繪制后的結果如下:
實驗代碼及注釋
image = imread('source.png'); [height, width] = size(image); image1 = double(image); %求出所有像素之和 sum_num = 0; for a = 1:1:height-1 for b = 1:1:width-1 sum_num = sum_num+image1(a,b);%如果使用image(a,b),則有可能出現錯誤的結果 end end for a = 1:1:height-1 for b = 1:1:width-1 image1(a,b) = image1(a,b)/sum_num; end end low1 = 115;high1 = 160;low2 = 100;high2 = 140; %采用mesh()函數繪圖效果 figure; max_val = max(max(image1)) [x, y] = meshgrid(low1:high1,low2:high2); z = image1(low2:high2,low1:high1); %%注意這里的順序,先給的是列坐標 mesh(x, y, z) axis([low1 high1 low2 high2 0 max_val]) xlabel('Cr'); ylabel('Cb'); %采用surf1()函數繪圖效果 figure; low1 = 115;high1 = 160;low2 = 100;high2 = 140; max_val = max(max(image1)) [x, y] = meshgrid(low1:high1,low2:high2); z = image1(low2:high2,low1:high1); %%注意這里的順序,先給的是列坐標 surfl(x, y, z) axis([low1 high1 low2 high2 0 max_val]) xlabel('Cr'); ylabel('Cb');
實驗總結: matlab編程和c/c++的風格不同,需要加以區別。