当前位置:编程学习 > Delphi >>

Delphi图像处理 -- USM锐化

 
 
    USM锐化是用来锐化图像边缘的,它通过调整图像边缘细节的对比度,并在边缘的两侧生成一条亮线一条暗线,使画面整体更加清晰。
 
    USM锐化用公式描述很麻烦,这里干脆实现步骤列于下面:
 
    1、备份图像原数据;
 
    2、按给定半径对图像进行高斯模糊;
 
    3、用原像素与高斯模糊后的像素相减,形成一个差值;
 
    4、将差值乘以数量;
 
    5、将差值分为正负2部分,取绝对值;
 
    6、正负差值分别减去给定的阈值;
 
    7、原像素加上正差值减去负差值,锐化完毕。
 
    下面是USM锐化代码,包括高斯模糊代码(关于高斯模糊见文章《Delphi图像处理 -- 高斯模糊》,下面的高斯模糊代码也是从该文拷贝来的):
 
[delphi]  
procedure CrossBlur(var Dest: TImageData; const Source: TImageData; Weights: Pointer; Radius: Integer);  
var  
  height, srcStride: Integer;  
  dstOffset, srcOffset: Integer;  
asm  
    push      esi  
    push      edi  
    push      ebx  
    push      ecx  
    mov       ecx, [edx].TImageData.Stride  
    mov       srcStride, ecx  
    call      _SetCopyRegs  
    mov       height, edx  
    mov       srcOffset, eax  
    mov       dstOffset, ebx  
    pop       ebx  
    pxor      xmm7, xmm7  
    push      esi           // pst = Source.Scan0   
    push      edi  
    push      edx  
    push      ecx  
  
    // blur col   
  
    mov       eax, srcStride  
    mov       edx, eax  
    shr       edx, 2        // width = Source.Width   
    mov       edi, Radius  
    shl       edi, 1  
    imul      edi, eax  
    add       edi, esi      // psb = pst + Radius * 2 * Source.Stride   
@@cyLoop:  
    push      edx  
@@cxLoop:  
    push      esi  
    push      edi  
    push      ebx  
    mov       ecx, Radius  
    pxor      xmm0, xmm0    // sum = 0   
@@cblurLoop:  
    movd      xmm1, [esi]   // for (i = 0; i < Radius; i ++)   
    movd      xmm2, [edi]   // {   
    punpcklbw xmm1, xmm7  
    punpcklbw xmm2, xmm7  
    paddw     xmm1, xmm2    //   ps = pst + psb   
    punpcklwd xmm1, xmm7  
    cvtdq2ps  xmm1, xmm1    //   pfs (flaot * 4) = ps (int * 4)   
    mulps     xmm1, [ebx]   //   pfs *= Weights[i]   
    addps     xmm0, xmm1    //   sum += pfs   
    add       ebx, 16  
    add       esi, eax      //   pst += Source.Stride   
    sub       edi, eax      //   psb -= Source.Stride   
    loop      @@cblurLoop   // }   
    movd      xmm1, [esi]  
    punpcklbw xmm1, xmm7  
    punpcklwd xmm1, xmm7  
    cvtdq2ps  xmm1, xmm1    // pfs (flaot * 4) = pst (int * 4)   
    mulps     xmm1, [ebx]   // pfs *= Weights[Radius]   
    addps     xmm0, xmm1    // sum += pfs   
    pop       ebx  
    pop       edi  
    pop       esi  
    cvtps2dq  xmm0, xmm0    // ps (int * 4) = sum (flaot * 4)   
    packssdw  xmm0, xmm7  
    packuswb  xmm0, xmm7  
    movd      [esi], xmm0   // pst (byte * 4) = ps (int * 4) pask   
    add       esi, 4  
    add       edi, 4  
    dec       edx  
    jnz       @@cxLoop  
    pop       edx  
    dec       height  
    jnz       @@cyLoop  
  
    pop       edx  
    pop       height  
    pop       edi           // pd = Dest.Scan0   
    pop       esi           // psl = pst   
    mov       eax, Radius  
    shl       eax, 1+2  
    add       eax, esi      // psr = psl + Radius * 2   
  
    // blur row   
  
@@ryLoop:  
    push      edx           // width = Dest.Width   
@@rxLoop:  
    push      esi  
    push      ebx  
    push      eax  
    mov       ecx, Radius  
    pxor      xmm0, xmm0    // sum = 0   
@@rblurLoop:  
    movd      xmm1, [esi]   // for (i = 0; i < Radius; i ++)   
    movd      xmm2, [eax]   // {   
    punpcklbw xmm1, xmm7  
    punpcklbw xmm2, xmm7  
    paddw     xmm1, xmm2    //   ps = psl + psr   
   
补充:软件开发 , Delphi ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,