基於法線的邊緣檢測

2021-06-08 23:59:07 字數 1694 閱讀 6984

在邊緣高亮效果

中我提到過兩種方法, 各有優缺點吧

影象空間域的邊緣檢測效果比較好, 中間沒有多餘的線條. 缺點是ps中計算比較慢

第二種把模型"放大"(其實是變胖)的做法, 可以在vs中完成, 不需要額外的rendertarget, 適合低端顯示卡使用, 適應性好. 不如果模型法線資訊不對的話, 會造成畫面錯亂. 實際使用時可以根據w值(不用z深度)來畫出遠近粗細一樣的線條

這次提到的基於法線的方法, 其實跟2d的空間域邊緣檢測很相似, 如果要求結果是繪製物體的線條圖而不僅僅是乙個邊緣輪廓時, 它就派上用場了. (還是要用ps去算, 實際使用時要注意效能問題)

基本的渲染流程(2 pass):

第乙個pass用於生成法線圖到一張rendertarget上, 第二個pass跟據這張法線圖來做邊緣檢測.

實際使用時可以採用multi-rendertarget來加速

法線資訊要在pixel shader裡進行向量化, 不然會在一些面上出塊很淡的顏色. 如果對質量要求不高, 可以在vs中進行向量化.

rendertarget要clear成單位化的值, 我用的(0,0,1), 即純藍色

[cpp]view plain

copy

print?

/*********************vs*********************/

float4x4 matviewprojection;  

struct vs_input   

;  struct vs_output   

;  vs_output vs_main( vs_input input )  

/*********************ps*********************/

float4 ps_main(float3 normal : texcoord0) : color0    

注意法線圖的格式是浮點數格式, 我用的是d3dfmt_a16b16g16r16f(因為法線有負值, 你也可以自己壓縮到[0,1]再解開)

有了這張法線圖就很好辦了, 對每個畫素計算它與周圍畫素的法線夾角余弦值的和, 再取反(1-degree), 這樣就能計算出來邊緣了

依據就是邊緣處的法線夾角比較大, 余弦值更接近0甚至為負值.

[cpp]view plain

copy

print?

sampler texnormal;  

float2 finverseviewportdimensions;  

float2 pixelkernel[4] =  

,  ,  

,    

};  

float4 ps_main(float2 texcoord : texcoord0) : color0  

return float4(sum, 1.0f);  

}  

最終效果:

分享到:

基於邊緣檢測的車牌定位

剛開始接觸影象處理做的試驗專案,想法比較簡單,限制多弊端較大,對質量要求比較高,如果灰度變化太大又或者預處理後得到的二值影象的連通區域出現與車牌所處區域面積相近,效果就差了很多。影象的預處理是通過增加對比度以及形態學處理得到的。想要得到理想效果需要多次重複操作。有很多不足之處,還請各位大神指教。直接...

演算法 基於OpenCV的Canny邊緣檢測演算法

canny邊緣檢測運算元是john f.canny於 1986 年開發出來的乙個多級邊緣檢測演算法。更為重要的是 canny 創立了邊緣檢測計算理論解釋這項技術如何工作。canny邊緣檢測演算法可以分為以下5個步驟 canny邊緣檢測的公式推導 高斯濾波 對影象進行平滑處理 計算梯度幅度和方向 採用...

基於二階微分的邊緣檢測方法

兩種laplacian模板 附件中 gauss lanlancian運算元 附件中 laplacian 運算元是二階導數邊緣運算元,考察的是3 3鄰域,上圖是兩種比較常用的模板,演算法簡述如下 遍歷影象 除去邊緣,防止越界 對每個畫素做laplancian模板卷積運算,注意是只做其中的一種模板運算,...