zoukankan      html  css  js  c++  java
  • Delphi图像处理 -- 最小值

    阅读提示:

        《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。

        《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。

        尽可能保持二者内容一致,可相互对照。

        本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元

        图像的最小值处理就是以当前像素为中心,取周边一定半径范围内的所有像素的RGB分量的最小值,作为当前像素的分量值。如果图像含Alpha信息,则应对Alpha分量作一个相反的处理,即最大值处理。 

    procedure DoMinValue(var Dest: TImageData; const Source: TImageData; Radius: Integer);
    var
      height, iOffset, jOffset, dstOffset, srcOffset: Integer;
    asm
        push      esi
        push      edi
        push      ebx
        push      ecx
        shl       ecx, 1
        mov       ebx, [edx].TImageData.Stride
        imul      ebx, ecx
        shl       ecx, 2
        add       ebx, ecx
        sub       ebx, 4
        neg       ebx
        mov       iOffset, ebx
        mov       ebx, [edx].TImageData.Stride
        push      ebx
        shl       ebx, 1
        sub       ebx, ecx
        mov       jOffset, ebx
        call      _SetCopyRegs
        mov       dstOffset, ebx
        mov       srcOffset, eax
        mov       height, edx
        pop       ebx
        pop       eax
    @@yLoop:
        push      ecx
    @@xLoop:
        mov       edx, eax
        pcmpeqb   mm0, mm0
        movq      mm1, mm0
        movq      mm2, mm0
    @@iLoop:
        push      eax
    @@jLoop:
        pminub    mm1, [esi]
        pminub    mm2, [esi+ebx]
        add       esi, 8
        dec       eax
        jnz       @@jLoop
        movd      mm3, [esi]
        movd      mm4, [esi+ebx]
        pminub    mm0, mm3
        pminub    mm0, mm4
        pop       eax
        add       esi, jOffset
        dec       edx
        jnz       @@iLoop
        push      eax
    @@jlLoop:
        pminub    mm1, [esi]
        add       esi, 8
        dec       eax
        jnz       @@jlLoop
        movd      mm3, [esi]
        pminub    mm0, mm3
        pop       eax
        pminub    mm0, mm1
        pminub    mm0, mm2
        psrlq     mm1, 32
        psrlq     mm2, 32
        pminub    mm0, mm1
        pminub    mm0, mm2
        movd      [edi], mm0
        add       esi, iOffset
        add       edi, 4
        loop      @@xLoop
        pop       ecx
        add       esi, srcOffset
        add       edi, dstOffset
        dec       height
        jnz       @@yLoop
        pop       ebx
        pop       edi
        pop       esi
        emms
    end;
    
    procedure DoMaxAlpha(var Dest: TImageData; const Source: TImageData; Radius: Integer);
    var
      height, iOffset, jOffset, dstOffset, srcOffset: Integer;
    asm
        push      esi
        push      edi
        push      ebx
        shl       ecx, 1
        inc       ecx
        push      ecx
        mov       ebx, [edx].TImageData.Stride
        imul      ebx, ecx
        sub       ebx, 4
        neg       ebx
        mov       iOffset, ebx
        shl       ecx, 2
        mov       ebx, [edx].TImageData.Stride
        sub       ebx, ecx
        mov       jOffset, ebx
        call      _SetCopyRegs
        mov       dstOffset, ebx
        mov       srcOffset, eax
        mov       height, edx
        add       esi, 3
        add       edi, 3
        pop       edx
    @@yLoop:
        push      ecx
    @@xLoop:
        mov       ebx, edx
        xor       eax, eax
    @@iLoop:
        push      edx
    @@jLoop:
        cmp       al, [esi]
        jae       @@1
        mov       al, [esi]
    @@1:
        add       esi, 4
        dec       edx
        jnz       @@jLoop
        pop       edx
        add       esi, jOffset
        dec       ebx
        jnz       @@iLoop
        mov       [edi], al
        add       esi, iOffset
        add       edi, 4
        loop      @@xLoop
        pop       ecx
        add       esi, srcOffset
        add       edi, dstOffset
        dec       height
        jnz       @@yLoop
        pop       ebx
        pop       edi
        pop       esi
    end;
    
    // 图像数据最小值处理。参数:图像数据,半径
    procedure ImageMinValue(var Data: TImageData; Radius: Integer);
    var
      src: TImageData;
    begin
      if Data.AlphaFlag then
        ArgbConvertPArgb(Data);           // 如果图像数据含Alpha信息,转换为PARGB
      src := _GetExpandData(Data, Radius);// 获取扩展半径后的图像数据源
      DoMinValue(Data, src, Radius);      // 图像数据的最小值处理
      if Data.AlphaFlag then              // 如果图像数据含Alpha信息
      begin
        DoMaxAlpha(Data, src, Radius);    // Alpha分量作最大值处理
        PArgbConvertArgb(Data);           // 还原PARGB为ARGB
      end;
      FreeImageData(src);
    end;
    

        调用例子及运行效果:

    procedure TForm1.Button3Click(Sender: TObject);
    var
      bmp: TGpBitmap;
      g: TGpGraphics;
      data: TImageData;
    begin
    //  bmp := TGpBitmap.Create('....mediaapple.png');
      bmp := TGpBitmap.Create('....mediasource.bmp');
      data := LockGpBitmap(bmp);
      ImageMinValue(data, 3);
      UnlockGpBitmap(bmp, data);
      g := TGpGraphics.Create(Canvas.Handle);
      g.DrawImage(bmp, 140, 0);
      g.Free;
      bmp.Free;
    end;
    



     

        《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。

        因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:maozefa@hotmail.com

        这里可访问《Delphi图像处理 -- 文章索引》。

  • 相关阅读:
    mysql data type <----> java data type (数值)
    line number is important in Exceptions.
    dom4j 使用原生xpath 处理带命名空间的文档
    dom4j 通过 org.dom4j.XPath 设置命名空间来支持 带namespace 的 xpath
    dom4j 创建一个带命名空间的pom.xml 文件
    xml to xsd ; xsd to xml
    sax 动态切换 抓取感兴趣的内容(把element当做documnet 处理)
    d3.js <一>
    python学习进阶一
    Java *字格
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3194115.html
Copyright © 2011-2022 走看看