Delphi影像處理 — 表面模糊

來源:互聯網
上載者:User

閱讀提示:

    《Delphi影像處理》系列以效率為側重點,一般代碼為PASCAL,核心代碼採用BASM。

    《C++影像處理》系列以代碼清晰,可讀性為主,全部使用C++代碼。

    儘可能保持二者內容一致,可相互對照。

   本文代碼必須包括文章《Delphi影像處理 -- 資料類型及公用過程》中的ImageData.pas單元。

    映像的表面模糊處理是Photoshop CS2以後才有的新功能,其作用是在保留映像邊緣的情況下,對映像的表面進行模糊處理。在對人物皮膚處理上,比高斯模糊更有效。因為高斯模糊在使人物皮膚光潔的同時,也將一些邊緣特徵如臉部的眉毛、嘴唇等給模糊了,不得不用蒙版小心的抹去這些地方的模糊部分。

    在處理手法上,表面模糊也與其它卷積處理手段不同,如高斯模糊等在處理映像時都是採用統一的卷積矩陣進行,而表面模糊卻是每一個像素點都有自己的卷積矩陣,而且還是3(4)套,用以對應於像素的R、G、B(A、R、G、B)分量。所以表面模糊在編程處理時,比其它卷積操作更複雜、更耗時,因為它要對每一個像素計算自己的卷積矩陣。表面模糊編程的痛點也在計算卷積矩陣上,其它與一般映像卷積處理一樣。

    表面模糊處理有2個參數,即模糊半徑和模糊閾值,前者確定模糊的範圍,後者確定模糊的程度。模糊範圍就是卷積矩陣大小,如模糊半徑為1,則模糊矩陣直徑為1*2+1等於3,矩陣元素個數為3*3等於9,矩陣的中間元素即是當前像素點。

    矩陣元素值的計算公式為:

    1) mij = 1 - (|pij - p0|) / 2.5T

    變形後可得:

    2) mij = (2.5T - ([pij - p0])) / 2.5T

    其中,mij為矩陣的各元素值,pij為矩陣元素對應的像素分量值,p0為矩陣中心元素對應的像素分量值,T為閾值,|pij - p0|為矩陣元素對應像素分量值與中心元素對應像素分量值的絕對差值。如果mij < 0,則mij = 0。

    對ARGB格式映像資料來說,因有4個分量,故需要4套卷積矩陣。

    矩陣元素確定後,就可按照一般映像卷積操作進行處理了,即分別累計矩陣元素值和與之對應的像素分量值乘積,用累計像素分量值除以累計元素值,即可得到當前像素分量模糊處理後的值。

    下面是表面模糊處理代碼:

// ARGB映像資料表面模糊處理.// 參數: 映像資料, 模糊半徑, 閾值procedure SurfaceBlur(var Data: TImageData; Radius, Threshold: Integer);const  _fc2_5: Single = 2.5;var  width, height, size: Integer;  srcOffset, dstOffset: Integer;  src: TImageData;begin  if not (Radius in [1..100]) or not (Threshold in [2..255]) then Exit;  if Data.AlphaFlag then              // 如果映像資料含Alpha資訊, 轉換為PARGB格式    ArgbConvertPArgb(Data);  src := _GetExpandData(Data, Radius);// 擷取擴充半徑後的備份映像資料  asm    push      esi    push      edi    push      ebx    mov       eax, Data    lea       edx, src    call      _SetCopyRegs    mov       width, ecx    mov       height, edx    mov       srcOffset, eax    mov       dstOffset, ebx    mov       eax, src.Stride    mov       ebx, Radius    shl       ebx, 1    inc       ebx    mov       size, ebx    shl       ebx, 2    neg       ebx    add       ebx, eax    add       eax, 4    mul       Radius    pxor      xmm7, xmm7    cvtsi2ss  xmm6, Threshold // xmm6 = 4 * (Threshold * 2.5)    movss     xmm0, _fc2_5    mulss     xmm6, xmm0    pshufd    xmm6, xmm6, 0@@yLoop:    push      width@@xLoop:    push      esi    mov       edx, Size    pxor      xmm0, xmm0      // Total Pixels    pxor      xmm5, xmm5      // Nuclear    movd      xmm4, [esi+eax] // xmm4 = p0 = 4 * word(a,r,g,b)    punpcklbw xmm4, xmm7@@iLoop:    mov       ecx, Size@@jLoop:    movd      xmm3, [esi]    punpcklbw xmm3, xmm7    movaps    xmm1, xmm3    movaps    xmm2, xmm4    // 計算模糊矩陣元素值    psubw     xmm1, xmm4      // xmm1 = xij - x0    psubw     xmm2, xmm3      // xmm2 = x0 - xij    packuswb  xmm1, xmm7      // 位元組飽和去掉xmm1中各分量差值中的負值    packuswb  xmm2, xmm7      // 位元組飽和去掉xmm2中各分量差值中的負值    por       xmm2, xmm1      // xmm2 = |xij - x0|    punpcklbw xmm2, xmm7    punpcklwd xmm2, xmm7    punpcklwd xmm3, xmm7    cvtdq2ps  xmm3, xmm3    cvtdq2ps  xmm2, xmm2    movaps    xmm1, xmm6    subps     xmm1, xmm2    divps     xmm1, xmm6      // xmm1 = (xmm6 - xmm2) / xmm6    maxps     xmm1, xmm7      // 去掉xmm1中的負值    mulps     xmm3, xmm1      // xij *= xmm1    // 累計模糊矩陣元素值和與對應像素值的乘積    addps     xmm5, xmm1      // Nuclear += xmm1    addps     xmm0, xmm3      // Total Pixels += xij    add       esi, 4    loop      @@jLoop    add       esi, ebx    dec       edx    jnz       @@iLoop    divps     xmm0, xmm5      // p0 = Total Pixels /= Nuclear    cvtps2dq  xmm0, xmm0    packssdw  xmm0, xmm7    packuswb  xmm0, xmm7    movd      [edi], xmm0    pop       esi    add       esi, 4    add       edi, 4    dec       width    jnz       @@xLoop    pop       width    add       esi, srcOffset    add       edi, dstOffset    dec       height    jnz       @@yLoop    pop       ebx    pop       edi    pop       esi  end;  FreeImageData(src);  if Data.AlphaFlag then      // 如果映像資料含Alpha資訊, 還原為ARGB格式    PArgbConvertArgb(Data);end;

    例子運行效果:

    《Delphi影像處理》系列使用GDI+單元和說明見文章《GDI+ for VCL基礎 -- GDI+ 與 VCL》。

    因水平有限,錯誤在所難免,歡迎指正和指導。郵箱地址:maozefa@hotmail.com

    這裡可訪問《Delphi影像處理 -- 文章索引》。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.