Delphi影像處理 — 中值濾波

來源:互聯網
上載者:User

閱讀提示:

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

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

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

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

 

    映像的中值濾波,就是在以某一像素為中心的n階像素矩陣中,找出R、G、B各分量的中間值來分別替代該像素的RGB值,從而達到對映像雜訊濾波的目的。這裡的中間值並非像素矩陣R、G、B各分量的的算術平均值,而是像素矩陣R、G、B各分量排序後的中位元值。

    下面是Delphi映像中值濾波的實現代碼:

 

procedure MedianValues(var Dest: TImageData; const Source: TImageData;  buf: Pointer; SortSize, Size, MatrixOffset: Integer);var  width, height: Integer;  dstOffset, srcOffset: Integer;  median: Pointer;  procedure MedianSort;  asm    mov     edx, edi            // i = count - 1    mov     al, [esi]           // al = r(gb)  @@Loop:                       // while (i >= 0 && buf[i].r(rb) > al) i --;    sub     edx, 4    js      @@1    cmp     al, [ebx+edx]    jb      @@Loop  @@1:    add     edx, 4              // i ++    mov     ecx, edi            //  @@moveLoop:    cmp     ecx, edx            // memmove(buf[i], buf[i+1], count - i)    je      @@2    mov     ah, [ebx+ecx-4]    mov     [ebx+ecx], ah    sub     ecx, 4    jmp     @@moveLoop  @@2:    mov     [ebx+edx], al       // buf[i] = al    inc     ebx    inc     esi  end;asm    push    esi    push    edi    push    ebx    push    ecx    call    _SetCopyRegs    mov     width, ecx    mov     height, edx    mov     dstOffset, ebx    mov     srcOffset, eax    pop     ebx    mov     eax, ebx    add     eax, SortSize    sub     eax, 4    mov     median, eax@@yLoop:    push    width@@xLoop:    push    esi    push    edi    xor     edi, edi    mov     ecx, Size@@iLoop:    push    ecx    mov     ecx, Size@@jLoop:    push    ecx    call    MedianSort    call    MedianSort    call    MedianSort    inc     esi    sub     ebx, 3    cmp     edi, SortSize    je      @@1    add     edi, 4@@1:    pop     ecx    loop    @@jLoop    add     esi, MatrixOffset    pop     ecx    loop    @@iLoop    pop     edi    pop     esi    mov     eax, median    mov     eax, [eax]    mov     cl, [edi].TARGBQuad.Alpha    mov     [edi], eax    mov     [edi].TARGBQuad.Alpha, cl    add     esi, 4    add     edi, 4    dec     width    jnz     @@xLoop    add     esi, srcOffset    add     edi, dstOffset    pop     width    dec     height    jnz     @@yLoop    pop     ebx    pop     edi    pop     esiend;procedure MedianValues3(var Dest: TImageData; const Source: TImageData; buf: Pointer; MatrixOffset: Integer);var  width, height: Integer;  dstOffset, srcOffset: Integer;  median: Pointer;  procedure AssortValue;  asm    mov     ah, [esi]    mov     dl, [esi+4]    mov     al, [esi+8]    cmp     ah, al    jae     @@1    xchg    ah, al  @@1:    cmp     ah, dl    jae     @@2    xchg    ah, dl  @@2:    cmp     al, dl    jbe     @@3    xchg    al, dl  @@3:    mov     [ebx], ah           // ah = large    mov     [ebx+4], dl         // dl = center    mov     [ebx+8], al         // al = small    inc     esi    inc     ebx  end;  procedure GetValue;  asm    mov     ah, [ebx]           // large  group: ebx   ebx+12 ebx+24    mov     dl, [ebx+4]         // center group: ebx+4 ebx+16 ebx+28    mov     al, [ebx+8]         // small  group: ebx+8 ebx+20 ebx+32    mov     dh, [ebx+16]    cmp     ah, [ebx+12]        // ah = min of large group    jbe     @@1    mov     ah, [ebx+12]  @@1:    cmp     ah, [ebx+24]    jbe     @@2    mov     ah, [ebx+24]          @@2:    cmp     dh, dl    jae     @@3    xchg    dh, dl  @@3:    cmp     dh, [ebx+28]    jae     @@4    xchg    dh, [ebx+28]  @@4:    cmp     dl, [ebx+28]        // dl = median of center group    jae     @@5    mov     dl, [ebx+28]  @@5:    cmp     al, [ebx+20]        // al = max of small group    jae     @@6    mov     al, [ebx+20]  @@6:    cmp     al, [ebx+32]    jae     @@7    mov     al, [ebx+32]  @@7:    cmp     ah, al    jae     @@8    xchg    al, ah  @@8:    cmp     ah, dl    jae     @@9    xchg    ah, dl  @@9:    cmp     al, dl              // al = median of [ah, dl, al]    jae     @@10    mov     al, dl  @@10:    mov     [edi], al    inc     edi    inc     ebx  end;asm    push    esi    push    edi    push    ebx    push    ecx    call    _SetCopyRegs    mov     width, ecx    mov     height, edx    mov     dstOffset, ebx    mov     srcOffset, eax    add     MatrixOffset, 9    pop     ebx@@yLoop:    push    width@@xLoop:    push    esi    push    ebx    mov     ecx, 3@@mLoop:    call    AssortValue    call    AssortValue    call    AssortValue    add     ebx, 9    add     esi, MatrixOffset    loop    @@mLoop    pop     ebx    pop     esi    call    GetValue    call    GetValue    call    GetValue    add     esi, 4    sub     ebx, 3    inc     edi    dec     width    jnz     @@xLoop    add     esi, srcOffset    add     edi, dstOffset    pop     width    dec     height    jnz     @@yLoop    pop     ebx    pop     edi    pop     esiend;procedure ImageMedianValues(var Data: TImageData; Radius: Integer);var  exp: TImageData;  Buf: array of Byte;  Size, SortSize: Integer;  MatrixOffset: Integer;begin  Size := (Radius shl 1) + 1;  exp := _GetExpandData(Data, Radius);  MatrixOffset := exp.Stride - (Size shl 2);  try    if Radius = 1 then    begin      SetLength(Buf, 9 * Sizeof(TARGBQuad));      MedianValues3(Data, exp, Buf, MatrixOffset);    end    else    begin      SortSize := ((Size * Size + 1) shr 1) * Sizeof(TARGBQuad);      SetLength(Buf, SortSize + Sizeof(TARGBQuad));      MedianValues(Data, exp, Buf, SortSize, Size, MatrixOffset);    end;  finally    FreeImageData(exp);  end;end;

    由於中值濾波要對每個像素都採用n階矩陣排序的方法找出其R、G、B分量的中間值,因此該操作是非常耗時的。最大的耗時主要是排序過程,儘管本文中值濾波過程用了BASM代碼,但這個濾波過程還是較慢,顯然排序演算法是提高操作速度的關鍵,我實驗了多種排序演算法,都不理想,沒辦法,只好將最常用的3階中值濾波排序進行了改進,所以,本文中值濾波過程處理映像的3階中值濾波速度相對還是較快的;對於半徑大於1(即3*3以上的)的中值濾波排序,改為插入排序,只比較小於中值的資料,大於或等於中值的資料直接忽略,因為我們需要只是的中間值,對於大於中間值的資料排序無疑是浪費時間!如此節省了不少時間,處理時間比以前平均節省了20%。不過還是比較耗時。

    《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.