Delphi Image Processing-High Fidelity contrast

Source: Internet
Author: User

Reading Tips:

Delphi Image ProcessingThe series focuses on efficiency. The general code is Pascal, and the core code is BaSm.

C ++ Image ProcessingThe series focuses on code clarity and readability, and all uses C ++ code.

Make sure that the two items are consistent and can be compared with each other.

The code in this article must include the imagedata. Pas unit in "Delphi Image Processing-data type and public process.

 

Image High Fidelity contrast processing is simple. The procedure is as follows:

1. Back up original image data;

2. Perform Gaussian blur on the Image Based on the given radius;

3. Subtract the original pixel from the Gaussian Blur pixel to form a difference;

4. Increase the difference value by 128.

The following is a high-fidelity contrast code, including Gaussian fuzzy code (for details about Gaussian blur, see the article 《Delphi Image Processing-Gaussian blur, The following Gaussian fuzzy code is also copied from this article ):

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 XMM 2, 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 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, 4 // PSL ++ sub eax, 4 // PSR -- loop @ rblurloop //} movd xmm1, [esi] punpcklbw xmm1, xmm7 punpcklwd xmm1, xmm7 cvtdq2ps xmm1, xmm1 // PFS (flaot * 4) = PSL (int * 4) mulps xmm1, [EBX] // PFS * = weights [radius] addps xmm0, xmm1 // sum + = PFS cvtps2dq xmm0, xmm0 // PS (int * 4) = sum (flaot * 4) packssdw xmm0, xmm7 packuswb xmm0, xmm7 movd [EDI], xmm0 // Pd (byte * 4) = ps (int * 4) pask pop eax pop EBX pop ESI add eax, 4 Add ESI, 4 Add EDI, 4 Dec edX jnz @ rxloop add eax, srcoffset add ESI, srcoffset add EDI, dstoffset pop edX dec height jnz @ ryloop pop EBX pop EDI pop esiend; // --> st x // <-- st e ** x = 2 ** (x * log2 (E) function _ expon: extended; ASM fldl2e // y = x * Log2e fmul primary ST (0) // I = round (y) frndint fsub ST (1), St // F = Y-I fxch ST (1) // z = 2 ** F f2xm1 fld1 FADD fscale // result = z * 2 ** I fstp ST (1) end; function getweights (VAR buffer, weights: pointer; q: single; radius: integer): integer; const _ fcd1: single = 0.1; _ FC1: single = 1.0; _ FC2: single = 2.0; _ fc250: single = 250.0; fc_255: single = 255.0; var R: integer; V, qq2: Double; ASM mov R, ECx MoV ECx, eax unzip q fabs fcom _ fcd1 fstsw ax sahf Jae @ 1 then _ fcd1 fstp ST (1) // If (q <0.1) Q = 0.1 JMP @ 2 @ 1: fcom _ fc250 fstsw ax sahf jbe @ 2 then _ fc250 fstp ST (1) // If (q> 250) Q = 250 @ 2: fst q fmul _ FC2 fstp qq2 // qq2 = 2 * Q * q fwait mov eax, r test eax, eax JG @ 10 push eax // If (radius <= 0) fld1 // {fadd q // radius = ABS (q) + 1 fistp [esp]. integer fwait pop eax @ testrad IUS: // while (true) mov R, eax // {fldz // sum = 0 testloop: // For (r = radius; r> 0; r ++) fild R // {limit ST (0) fmulp ST (1), St fdiv qq2 fchs call _ expon // TMP = exp (-(R * r) /(2.0 * Q * q); cmp r, eax JNE @ 3 FST v // If (r = radius) V = TMP @ 3: faddp ST (1), ST (0) // sum + = TMP dec R jnz @ testloop //} fmul _ FC2 // sum * = 2 FADD _ FC1 // sum + = 1 fdivr v fmul _ fc255 fistp R cmp r, 0 je @ 4 // If (INT) (V/SUM * 255 + 0.5) = 0) break Inc eax // radius ++ JMP @ testradius //} @ 4: Dec eax jnz @ 5 Inc eax @ 5: mov R, eax //} @ 10: Inc eax SHL eax, 4 Add eax, 12 push edX push ECx mov edX, eax mov eax, ghnd call globalallocptr pop ECx pop edX test eax, eax JZ @ exit mov [ECx], eax // buffer = globalallocptr (ghnd, (radius + 1) * 16 + 12) add eax, 12 and eax, -16 mov [edX], eax // Wei Ghts = (char *) buffer + 12) & 0xfffffff0 mov ECx, r // ECx = radius mov edX, eax // edX = weights fldz // for (I = radius, sum = 0; I> 0; I --) @ clacloop: // {fild R limit ST (0) fmulp ST (1 ), st fdiv qq2 fchs call _ expon fstp [edX]. double // weights [I] = expon (-(I * I)/(2 * Q * q) FADD [edX]. double // sum + = weights [I] add edX, 16 dec R jnz @ clacloop //} fmul _ FC2 // sum * = 2 fld1 fstp [edX]. Double // weights [radius] = 1 FADD [edX]. double // sum + = weights [radius] Push ECx Inc ECx @ divloop: // for (I = 0; I <= radius; I ++) lead st (0) // weights [I] = round (weights [I]/SUM) fdivr [eax]. double FST [eax]. single FST [eax + 4]. single FST [eax + 8]. single fstp [eax + 12]. single add eax, 16 loop @ divloop Ffree ST (0) fwait pop eax/return radius @ Exit: end; // Gaussian blur. Procedure imagegaussiabblur (VAR data: timagedata; Q: single; radius: integer); var buffer, weights: pointer; SRC: timagedata; begin radius: = getweights (buffer, weights, Q, radius); If radius = 0 Then exit; if data. alphaflag then argbconvertpargb (data); SRC: = _ getexpanddata (data, radius); crossblur (data, SRC, weights, radius); freeimagedata (SRC); globalfreeptr (buffer ); if data. alphaflag then pargbconvertargb (data); end; Procedure dohighpass (var dest: timagedata; const Source: timagedata); ASM push ESI push EDI push EBX pxor mm7, mm7 mov ECx, 128 movd mm6, ECx pshufw mm6, mm6, 0 call _ setcopyregs @ yloop: Push ECx @ xloop: movd mm0, [esi] // mm0 = original pixel movd MM1, [EDI] // MM1 = pixel punpcklbw mm0 after Gaussian blur, mm7 punpcklbw MM1, mm7 psubw mm0, MM1 paddw mm0, mm6 // mm0 = mm0-MM1 + 128 packuswb mm0, mm7 movd [EDI], mm0 add ESI, 3 add EDI, 3 movsb loop @ xloop pop ECx add ESI, eax add EDI, EBX dec edX jnz @ yloop pop EBX pop EDI pop ESI emmsend; // High Fidelity contrast procedure imagehighpass (VAR data: timagedata; radius: single); procedcopyure data (var dest: timagedata; const Source: timagedata); ASM push ESI push EDI mov ECx, [eax]. timagedata. width imul ECx, [eax]. timagedata. height mov EDI, [eax]. timagedata. scan0 mov ESI, [edX]. timagedata. scan0 rep movsd pop EDI pop ESI end; var isinvertscan0: Boolean; SRC: timagedata; begin // back up image data SRC: = newimagedata (data. width, Data. height); isinvertscan0: = data. stride <0; If isinvertscan0 then _ invertscan0 (data); copydata (SRC, data); // use image data as Gaussian Blur imagegaussiabblur (data, radius, 0 ); // use backup image data and Gaussian fuzzy image data for High Fidelity contrast dohighpass (data, Src); freeimagedata (SRC); If isinvertscan0 then _ invertscan0 (data); end;

Simple Example:

procedure TForm1.Button2Click(Sender: TObject);var  bmp: TBitmap;  data: TImageData;begin  bmp := TBitmap.Create;  bmp.LoadFromFile('d:\source.bmp');  data := GetBitmapData(bmp);  ImageHighPass(Data, 3);  Canvas.Draw(0, 0, bmp);  bmp.Free;end;

The following figure shows the source image and the running interface of the example:

For details about the use of GDI + units and descriptions in the "Delphi image processing" series, see the article 《GDI + for VCL basics-GDI + and VCL.

Due to limited levels, errors are inevitable. Correction and guidance are welcome. Email Address:Maozefa@hotmail.com

Here, you can access "Delphi Image Processing-Article Index".

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.