DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: 123glimmer
今日帖子: 19
在线用户: 18
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 fb4819 (方明) ★☆☆☆☆ -
盒子活跃会员
2021/3/25 22:06:25
标题:
Java图像去噪代码翻译成Delphi,求助! 浏览:452
加入我的收藏
楼主: 网上找了段Java的图片去噪代码,Eclipse运行效果还不错,自己翻译成Delphi悲剧了,虽然也去噪了,但白色的背景变成黄色了,求大神指点下我的代码哪出错了,万分感谢感谢

原Java代码:
  public static void main(String[] args) throws IOException  {
        //源文件
        File testDataDir = new File("d:\\5.jpg");
        //处理后路径
        final String destDir = "d:\\ss";
        cleanLinesInImage(testDataDir, destDir);
    }
  
    public static void cleanLinesInImage(File sfile, String destDir)  throws IOException{
        File destF = new File(destDir);
        if (!destF.exists()) {
          destF.mkdirs();
        }

        BufferedImage bufferedImage = ImageIO.read(sfile);
        int h = bufferedImage.getHeight();
        int w = bufferedImage.getWidth();

        // 灰度化
        int[][] gray = new int[w][h];
        for (int x = 0; x < w; x++) {
          for (int y = 0; y < h; y++) {
          int argb = bufferedImage.getRGB(x, y);
          // 图像加亮(调整亮度识别率非常高)
          int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
          int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
          int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
          if (r >= 255) {
          r = 255;
          }
          if (g >= 255) {
          g = 255;
          }
          if (b >= 255) {
          b = 255;
          }
          gray[x][y] = (int) Math.pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2) * 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
          }
        }

        // 二值化
        int threshold = ostu(gray, w, h);
        BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
        for (int x = 0; x < w; x++) {
          for (int y = 0; y < h; y++) {
          if (gray[x][y] > threshold) {
          gray[x][y] |= 0x00FFFF;
          } else {
          gray[x][y] &= 0xFF0000;
        }
        binaryBufferedImage.setRGB(x, y, gray[x][y]);
          }
        }

        //去除干扰线条
        for(int y = 1; y < h-1; y++){
          for(int x = 1; x < w-1; x++){
          boolean flag = false ;
          if(isBlack(binaryBufferedImage.getRGB(x, y))){
          //左右均为空时,去掉此点
          if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){
          flag = true;
          }
          //上下均为空时,去掉此点
          if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){
          flag = true;
          }
          //斜上下为空时,去掉此点
          if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){
          flag = true;
          }
          if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){
          flag = true;
          }
          if(flag){
          binaryBufferedImage.setRGB(x,y,-1);
          }
          }
          }
        }


        // 矩阵打印
        for (int y = 0; y < h; y++) {
          for (int x = 0; x < w; x++) {
          if (isBlack(binaryBufferedImage.getRGB(x, y))) {
          System.out.print("*");
          } else {
          System.out.print(" ");
          }
          }
          System.out.println();
        }
        ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile.getName()));
    }

    public static boolean isBlack(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getRed() + color.getGreen() + color.getBlue() <= 300) {
          return true;
        }
        return false;
    }

    public static boolean isWhite(int colorInt) {
        Color color = new Color(colorInt);
        if (color.getRed() + color.getGreen() + color.getBlue() > 300) {
          return true;
        }
        return false;
    }

    public static int isBlackOrWhite(int colorInt) {
        if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) {
          return 1;
        }
        return 0;
    }

    public static int getColorBright(int colorInt) {
        Color color = new Color(colorInt);
        return color.getRed() + color.getGreen() + color.getBlue();
    }

    public static int ostu(int[][] gray, int w, int h){
        int[] histData = new int[w * h];
        // Calculate histogram
        for (int x = 0; x < w; x++) {
          for (int y = 0; y < h; y++){
          int red = 0xFF & gray[x][y];
          histData[red]++;
          }
        }
        // Total number of pixels
        int total = w * h;
        float sum = 0;
        for (int t = 0; t < 256; t++)
          sum += t * histData[t];
        float sumB = 0;
        int wB = 0;
        int wF = 0;
        float varMax = 0;
        int threshold = 0;
        for (int t = 0; t < 256; t++) {
          wB += histData[t]; // Weight Background
          if (wB == 0)
          continue;
          wF = total - wB; // Weight Foreground
          if (wF == 0)
          break;
          sumB += (float) (t * histData[t]);
          float mB = sumB / wB; // Mean Background
          float mF = (sum - sumB) / wF; // Mean Foreground\
          // Calculate Between Class Variance
          float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
          // Check if new maximum found
          if (varBetween > varMax) {
          varMax = varBetween;
          threshold = t;
          }
        }
        return threshold;
    }
}
**********我翻译的Delphi代码**********
function getRGB(Bitmap:TBitmap;x,y:Integer):Integer;
var p:PRGBTriple;
begin
  p:=bitmap.ScanLine[y];
  Inc(p,x);
  Result:=p^.rgbtBlue Shl 16 or p^.rgbtGreen shl 8 or p^.rgbtRed;
end;

procedure setRGB(Bitmap:TBitmap;x,y:Integer;colorInt:Integer);
var p:PRGBTriple;
begin
  bitmap.Canvas.Pixels[x,y]:=colorInt;
  p:=bitmap.ScanLine[y];
  Inc(p,x);
  p^.rgbtRed:=GetRValue(colorInt);
  p^.rgbtGreen:=GetGValue(colorInt);
  p^.rgbtBlue:=GetBValue(colorInt);
end;

function RGBToColor(R,G,B: byte): TColor;
begin
  Result := B Shl 16 or G shl 8 or R;
end;

procedure ColorToRGB(color:TColor;var R,G,B:Integer);
begin
  R := Color and $FF;
  G := (Color and $FF00) shr 8;
  B := (Color and $FF0000) shr 16;
end;

function RemoveBackgroud(src:TBitmap):TBitmap;
var
  p: PRGBTriple;
  x,y:Integer;
  c:TColor;
begin
  result := TBitmap.Create;
  result.Assign(src);
  Result.PixelFormat := pf24bit;
  for y := 0 to Result.Height - 1 do
  begin
    p:=Result.ScanLine[y];
    for x := 0 to Result.Width - 1 do
    begin
      c:=RGBToColor(p^.rgbtRed,p^.rgbtGreen,p^.rgbtBlue);
      if isWhite(c) then
      begin
        p^.rgbtRed:=255;
        p^.rgbtGreen:=255;
        p^.rgbtBlue:=255;
      end else
      begin
        p^.rgbtRed:=0;
        p^.rgbtGreen:=0;
        p^.rgbtBlue:=0;
      end;
      Inc(p);
    end;
  end;
end;

function isBlack(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b<=300;
end;

function isWhite(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b>300;
end;

function getColorBright(colorInt:Integer):Integer;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b;
end;

function isBlackOrWhite(colorInt:Integer):Integer;
begin
  if (getColorBright(colorInt)<30) or (getColorBright(colorInt)>730) then
    Result:=1 else
    Result:=0;
end;

function ostu(gray:MyInt;  w, h:Integer):Integer;
var
  hisData:array of Integer;
  Total,wB,wF,t,threshold,x,y:Integer;
  red:Byte;
  varBetween,mB,mF,varMax,sum,sumB:Single;
begin
  SetLength(hisData,w*h);
  for x:=0 to w-1 do
  begin
    for y:=0 to h-1 do
    begin
      red:=$FF and gray[x,y];
      hisData[red]:=hisData[red]+1;
    end;
  end;
  total := w * h;
  sum := 0;
  for t:=0 to 255 do
    sum:=sum+t*hisData[t];

  sumB := 0;
  wB := 0;
  varMax := 0;
  threshold := 0;
  for t:=0 to 255 do
  begin
    wB := wB+hisData[t]; // Weight Background
    if (wB = 0) then
        continue;

    wF := total - wB; // Weight Foreground
    if (wF = 0) then
        break;

    sumB := sumB+ (t * hisData[t]);

    mB := sumB / wB; // Mean Background
    mF := (sum - sumB) / wF; // Mean Foreground

    // Calculate Between Class Variance
    varBetween := wB *  wF * (mB - mF) * (mB - mF);

    // Check if new maximum found
    if (varBetween > varMax) then
    begin
      varMax := varBetween;
      threshold := t;
    end;
  end;
  Result:=threshold;
end;

procedure cleanLinesInImage(sfile,destDir:String);
var
  bufferedImage,binaryBufferedImage:TBitmap;
  argb,x,y,I,w,h,r,g,b,threshold:Integer;
  gray:MyInt;
  p: PRGBTriple;
  flag:Boolean;
begin
  bufferedImage:=TBitmap.Create ;
  bufferedImage.LoadFromFile(sfile);
  h := bufferedImage.Height;
  w := bufferedImage.Width;
  // 灰度化
  setLength(gray,w);
  for I:=0 to w-1 do
    SetLength(gray[I],h);
  for x := 0 to w-1 do
  begin
    for y := 0 to h-1 do
    begin
      argb:=bufferedImage.Canvas.Pixels[x,y];
      // 图像加亮(调整亮度识别率非常高)
      r :=  Trunc(((argb shl 16) and $FF) * 1.1 + 30);
      g :=  Trunc(((argb shl 8) and $FF) * 1.1 + 30);
      b :=  Trunc(((argb shl 0) and $FF) * 1.1 + 30);
      if (r >= 255) then
          r := 255;
      if (g >= 255) then
          g := 255;
      if (b >= 255) then
          b := 255;
      gray[x][y] := Trunc(Math.Power((Math.power(r, 2.2) * 0.2973 + Math.power(g, 2.2) * 0.6274 + Math.power(b, 2.2) * 0.0753), 1 / 2.2));
    end;
  end;
  // 二值化
  threshold := ostu(gray, w, h);
  binaryBufferedImage :=TBitmap.Create ;
  binaryBufferedImage.Width :=w;
  binaryBufferedImage.Height :=h;
  binaryBufferedImage.PixelFormat:=pf24bit;
  for y := 0 to h-1 do
  begin
    p:=binaryBufferedImage.ScanLine[y];
    for  x := 0 to w-1 do
    begin
      if (gray[x][y] > threshold) then
          gray[x][y] := gray[x][y] or $00FFFF else
          gray[x][y] := gray[x][y] and $FF0000;
      ColorToRGB(gray[x][y],r,g,b);
      p^.rgbtRed:=r;
      p^.rgbtGreen:=g;
      p^.rgbtBlue:=b;
      Inc(p);
    end;
  end;
  //去除干扰线条
  for y := 1 to  h-2 do
  begin
    p:=binaryBufferedImage.ScanLine[y];
    for  x := 1 to  w-2 do
    begin
      Inc(p);
      flag := false;
      if isBlack(RGBToColor(p^.rgbtRed,p^.rgbtGreen,p^.rgbtBlue)) then
      begin
        //左右均为空时,去掉此点
        if (isWhite(getRGB(binaryBufferedImage,x-1, y)) and isWhite(getRGB(binaryBufferedImage,x+1, y))) then
          flag := true;
        //上下均为空时,去掉此点
        if (isWhite(getRGB(binaryBufferedImage,x, y+1)) and isWhite(getRGB(binaryBufferedImage,x, y-1))) then
          flag := true;
        //斜上下为空时,去掉此点
        if (isWhite(getRGB(binaryBufferedImage,x-1, y+1)) and isWhite(getRGB(binaryBufferedImage,x+1, y-1))) then
          flag := true;
        if (isWhite(getRGB(binaryBufferedImage,x+1, y+1)) and isWhite(getRGB(binaryBufferedImage,x-1, y-1))) then
          flag := true;
        if (flag) then
          setRGB(binaryBufferedImage,x,y,-1);
      end;
    end;
  end;
  // 矩阵打印
//  for y := 0 to h-1 do
//  begin
//    for x := 0 to w-1 do
//    begin
//      if (isBlack(getRGB(binaryBufferedImage,x, y)))
//      begin
//          System.out.print("*");
//      end else
//      begin
//          System.out.print(" ");
//      end;
//    end;
//  end;
  binaryBufferedImage.SaveToFile(destDir);
end;
----------------------------------------------
vvvvvvvvvv
作者:
男 fb4819 (方明) ★☆☆☆☆ -
盒子活跃会员
2021/3/25 22:12:59
1楼: 原始图->Delphi代码转的
   |
   |
Java代码转的
此帖子包含附件:
PNG 图像
大小:15.9K
----------------------------------------------
vvvvvvvvvv
作者:
男 supermay (supermay) ★☆☆☆☆ -
盒子活跃会员
2021/3/26 16:06:41
2楼: function isWhite(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b>300;
end;
看看这个函数吧,跟踪一下这个值
----------------------------------------------
https://shop66090024.taobao.com/?spm=a313o.7775905.1998679131.d0011.6f6f2796Z7e3JX
作者:
男 fb4819 (方明) ★☆☆☆☆ -
盒子活跃会员
2021/3/26 16:56:05
3楼: 自己找到原因了,代码太长不贴了,需要的留个邮箱
----------------------------------------------
vvvvvvvvvv
作者:
男 142857 (142857) ★☆☆☆☆ -
盒子活跃会员
2021/3/26 17:33:31
4楼: dzmijia@aliyun.com 谢谢
----------------------------------------------
dddddd
作者:
男 aket (aket) ★☆☆☆☆ -
盒子活跃会员
2021/3/26 17:53:04
5楼: 412866575@qq.com thx
----------------------------------------------
-
作者:
男 keymark (keymark) ▲▲△△△ -
注册会员
2021/3/26 18:11:42
6楼: https://www.cnblogs.com/lackey/p/8904224.html
----------------------------------------------
播客
作者:
男 tulater (tulater) ★☆☆☆☆ -
普通会员
2021/3/26 18:36:14
7楼: 16130162@qq.com
谢谢了
----------------------------------------------
http://www.cnblogs.com/tulater/
作者:
男 lixe999 (lixe) ★☆☆☆☆ -
普通会员
2021/3/26 19:27:20
8楼: 331785884@qq.com
谢谢!
----------------------------------------------
-
作者:
男 fb4819 (方明) ★☆☆☆☆ -
盒子活跃会员
2021/3/26 20:40:24
9楼: 还是贴代码吧,长点就长点吧
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, jpeg,Math;

type
  MyInt=array of array of Integer;
  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array[0..4095] of TRGBTriple;

// 去除图片噪点 并将彩色转为纯色(黑色)
function removeBackgroud(src:TBitmap):TBitmap;
// 去噪
procedure cleanLinesInImage(bufferedImage,binaryBufferedImage:TBitmap);

function getRGB(Bitmap:TBitmap;x,y:Integer):Integer;
procedure setRGB(Bitmap:TBitmap;x,y:Integer;colorInt:Integer);

implementation

function getRGB(Bitmap:TBitmap;x,y:Integer):Integer;
var p:PRGBTripleArray;
begin
  p:=bitmap.ScanLine[y];
  Result:=p[x].rgbtBlue Shl 16 xor p[x].rgbtGreen shl 8 xor p[x].rgbtRed;
end;

procedure setRGB(Bitmap:TBitmap;x,y:Integer;colorInt:Integer);
var p:PRGBTripleArray;
begin
  p:=bitmap.ScanLine[y];
  p[x].rgbtRed:=GetRValue(colorInt);
  p[x].rgbtGreen:=GetGValue(colorInt);
  p[x].rgbtBlue:=GetBValue(colorInt);
end;

function RGBToColor(R,G,B: byte): TColor;
begin
  Result := B Shl 16 xor G shl 8 xor R;
end;

procedure ColorToRGB(color:TColor;var R,G,B:Integer);
begin
  R := Color and $FF;
  G := (Color and $FF00) shr 8;
  B := (Color and $FF0000) shr 16;
end;

function isWhite(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  if (r + g + b > 200) and (r + g + b < 500) then
    Result:=False else
    Result:=True;
end;

function RemoveBackgroud(src:TBitmap):TBitmap;
var
  p: PRGBTripleArray;
  x,y:Integer;
  c:TColor;
begin
  result := TBitmap.Create;
  result.Assign(src);
  Result.PixelFormat := pf24bit;
  for y := 0 to Result.Height - 1 do
  begin
    p:=Result.ScanLine[y];
    for x := 0 to Result.Width - 1 do
    begin
      c:=RGBToColor(p[x].rgbtRed,p[x].rgbtGreen,p[x].rgbtBlue);
      if isWhite(c) then
      begin
        p[x].rgbtRed:=255;
        p[x].rgbtGreen:=255;
        p[x].rgbtBlue:=255;
      end else
      begin
        p[x].rgbtRed:=0;
        p[x].rgbtGreen:=0;
        p[x].rgbtBlue:=0;
      end;
    end;
  end;
end;

function isBlack2(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b<=300;
end;

function isWhite2(colorInt:Integer):Boolean;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b>300;
end;


function getColorBright(colorInt:Integer):Integer;
var
  r,g,b:byte;
  c:LongInt;
begin
  c:=Graphics.ColorToRGB(colorInt);
  r:=GetRValue(c);
  g:=GetGValue(c);
  b:=GetBValue(c);
  Result:=r+g+b;
end;

function isBlackOrWhite(colorInt:Integer):Integer;
begin
  if (getColorBright(colorInt)<30) or (getColorBright(colorInt)>730) then
    Result:=1 else
    Result:=0;
end;

function ostu(gray:MyInt;  w, h:Integer):Integer;
var
  hisData:array of Integer;
  Total,wB,wF,t,threshold,x,y:Integer;
  red:Byte;
  varBetween,mB,mF,varMax,sum,sumB:Single;
begin
  SetLength(hisData,w*h);
  for x:=0 to w-1 do
  begin
    for y:=0 to h-1 do
    begin
      red:=$FF and gray[x,y];
      hisData[red]:=hisData[red]+1;
    end;
  end;
  total := w * h;
  sum := 0;
  for t:=0 to 255 do
    sum:=sum+t*hisData[t];

  sumB := 0;
  wB := 0;
  varMax := 0;
  threshold := 0;
  for t:=0 to 255 do
  begin
    wB := wB+hisData[t]; // Weight Background
    if (wB = 0) then
        continue;

    wF := total - wB; // Weight Foreground
    if (wF = 0) then
        break;

    sumB := sumB+ (t * hisData[t]);

    mB := sumB / wB; // Mean Background
    mF := (sum - sumB) / wF; // Mean Foreground

    // Calculate Between Class Variance
    varBetween := wB *  wF * (mB - mF) * (mB - mF);

    // Check if new maximum found
    if (varBetween > varMax) then
    begin
      varMax := varBetween;
      threshold := t;
    end;
  end;
  Result:=threshold;
end;

procedure cleanLinesInImage(bufferedImage,binaryBufferedImage:TBitmap);
var
  argb,x,y,I,w,h,r,g,b:Integer;
//  threshold:Integer;
  gray:MyInt;
  //p: PRGBTripleArray;
  flag:Boolean;
begin
  h := bufferedImage.Height;
  w := bufferedImage.Width;
  // 灰度化
  setLength(gray,w);
  for I:=0 to w-1 do
    SetLength(gray[I],h);
  for x := 0 to w-1 do
  begin
    for y := 0 to h-1 do
    begin
      argb:=getRGB(bufferedImage,x,y);
      // 图像加亮(调整亮度识别率非常高)
      r :=  Trunc(((argb shl 16) and $FF) * 1.1 + 30);
      g :=  Trunc(((argb shl 8) and $FF) * 1.1 + 30);
      b :=  Trunc(((argb shl 0) and $FF) * 1.1 + 30);
      if (r >= 255) then
          r := 255;
      if (g >= 255) then
          g := 255;
      if (b >= 255) then
          b := 255;
      gray[x][y] := Trunc(Math.Power((Math.power(r, 2.2) * 0.2973 + Math.power(g, 2.2) * 0.6274 + Math.power(b, 2.2) * 0.0753), 1 / 2.2));
    end;
  end;
  // 二值化
  //threshold := ostu(gray, w, h);
  //binaryBufferedImage :=TBitmap.Create ;
  binaryBufferedImage.Assign(bufferedImage);
  binaryBufferedImage.PixelFormat:=pf24bit;
//  for y := 0 to h-1 do
//  begin
//    for  x := 0 to w-1 do
//    begin
//      if (gray[x][y] > threshold) then
//          gray[x][y] := gray[x][y] xor $00FFFF else
//          gray[x][y] := gray[x][y] and $FF0000;
//      setRGB(binaryBufferedImage,x,y,gray[x,y]);
//    end;
//  end;
  //去除干扰线条
  for y := 1 to  h-2 do
  begin
    for  x := 1 to  w-2 do
    begin
      flag := false;
      if isBlack2(getRGB(binaryBufferedImage,x,y)) then
      begin
        //左右均为空时,去掉此点
        if (isWhite2(getRGB(binaryBufferedImage,x-1, y)) and isWhite2(getRGB(binaryBufferedImage,x+1, y))) then
          flag := true;
        //上下均为空时,去掉此点
        if (isWhite2(getRGB(binaryBufferedImage,x, y+1)) and isWhite2(getRGB(binaryBufferedImage,x, y-1))) then
          flag := true;
        //斜上下为空时,去掉此点
        if (isWhite2(getRGB(binaryBufferedImage,x-1, y+1)) and isWhite2(getRGB(binaryBufferedImage,x+1, y-1))) then
          flag := true;
        if (isWhite2(getRGB(binaryBufferedImage,x+1, y+1)) and isWhite2(getRGB(binaryBufferedImage,x-1, y-1))) then
          flag := true;
        if (flag) then
          setRGB(binaryBufferedImage,x,y,-1);
      end;
    end;
  end;
end;
----------------------------------------------
vvvvvvvvvv
作者:
男 lordaeron (Terry) ★☆☆☆☆ -
注册会员
2021/3/26 21:47:30
10楼: 我的看法, 它是GRAYSCALE 是8 BIT COLOR 的,JAVA 版使用的是TYPE_BYTE_BINARY
但你的DELPHI 版是使用pf24bit
公式


To convert 8bit [0 - 255] value into 3bit [0, 7], the 0 is not a problem, but remember 255 should be converted to 7, so the formula should be Red3 = Red8 * 7 / 255.

To convert 24bit color into 8bit,

8bit Color = (Red * 7 / 255) << 5 + (Green * 7 / 255) << 2 + (Blue * 3 / 255)

To reverse,

Red   = (Color >> 5) * 255 / 7
Green = ((Color >> 2) & 0x07) * 255 / 7
Blue  = (Color & 0x03) * 255 / 3
----------------------------------------------
-
作者:
男 akai1203 (w-dins) ★☆☆☆☆ -
普通会员
2021/3/27 14:48:20
11楼: 支持
----------------------------------------------
-把学习当信仰
作者:
男 lordaeron (Terry) ★☆☆☆☆ -
注册会员
2021/3/29 12:03:37
12楼: 這昰我的JAVA TO PASCAL 轉換,結果和JAVA一致。 
var
   bufferedImage,binaryBufferedImage:Graphics.TBitmap;
   h,w,x,x1,x2,x3,y,threshold:integer;
   gray:TArr2D;
   p1,p2,p3:pbyte;
   flag:boolean;
   r,g,b:double;
    c:LongInt;
begin
    bufferedImage := Graphics.TBitmap.Create;
    bufferedImage.LoadFromFile('denoise.bmp');
    h := bufferedImage.Height;
    w := bufferedImage.Width;
    SetLength(gray, w, h);
    // 灰度化
    for x := 0 to w - 1 do
    begin
      x1:=x*3;
      for y := 0 to h - 1 do
      begin
        p1 := bufferedImage.scanline[y];
        // 圖像加亮(調整亮度識別率非常高)
        r := (double(p1[x1]) * double(1.1) + 30.0);
        g := (double(p1[x1+1]) * double(1.1) + 30.0);
        b := (double(p1[x1+2]) * double(1.1) + 30.0);
        if (r >= 255) then
        begin
          r := 255;
        end;
        if (g >= 255) then
        begin
          g := 255;
        end;
        if (b >= 255) then
        begin
          b := 255;
        end;
        gray[x][y] := Trunc(Power((Power(r, 2.2) * 0.2973 + Power(g, 2.2) * 0.6274 + Power(b, 2.2) * 0.0753), 1 / 2.2));
      end;
    end;

    // 二值化
    threshold := ostu(gray, w, h);
    panel1.Caption:='threshold:'+inttostr(threshold);
    binaryBufferedImage := Graphics.TBitmap.Create;
    binaryBufferedImage.SetSize(w,h);
    binaryBufferedImage.PixelFormat:=pf24bit;
    binaryBufferedImage.BeginUpdate();
    for x := 0 to w -1 do
    begin
      x1:=x*3;
      for y := 0 to h -1 do
      begin
        //怪的地方在這,它的目的是大於threshold 的為白,不然為黑。
       //由於這段會導致GRAY的人值大於255(灰階只有255階)
      //所以轉回RGB 時,作GRAY 的內容作AND 拿回黑/白兩色。 
        if (gray[x][y] > threshold) then
        begin
          gray[x][y] :=gray[x][y] or $00FFFF;
        end
        else
        begin
          gray[x][y] :=gray[x][y] and $FF0000;
        end;
        p1:=binaryBufferedImage.scanline[y];

        r:=double(gray[x][y] and $FF shr 5) * 255.0 / 7.0; {Red}
        g:=double((gray[x][y]  and $FF shr 2) and $07) * 255.0 / 7.0; {Green}
        b:=double(gray[x][y] and $FF and $03) * 255.0 / 3.0;  {Blue}
   
        p1[x1]   :=trunc(r);
        p1[x1+1] :=trunc(g);
        p1[x1+2] :=trunc(b);
      end;
    end;

    //去除干擾線條
    for y := 1 to h-2 do
    begin
      for x := 1 to w-2 do
      begin
        flag := false ;
        x1:=x*3;
        p1:=binaryBufferedImage.scanline[y];
        if (p1[x1]+p1[x1+1]+p1[x1+2]<= 300) then
        begin
          x2:=(x-1)*3;
          x3:=(x+1)*3;
          //左右均為空時,去掉此點
          if (p1[x2]+p1[x2+1]+p1[x2+2] > 300) and (p1[x3]+p1[x3+1]+p1[x3+2] > 300) then
          begin
          flag := true;
          end
          else
          begin
          p2:=binaryBufferedImage.scanline[y-1];
          p3:=binaryBufferedImage.scanline[y+1];
          //上下均為空時,去掉此點
          if (p2[x1]+p2[x1+1]+p2[x1+2] > 300) and (p3[x1]+p3[x1+1]+p3[x1+2] > 300) then
          begin
          flag := true;
          end
          else
          //斜上下為空時,去掉此點
          if (p2[x2]+p2[x2+1]+p2[x2+2] > 300) and (p3[x3]+p3[x3+1]+p3[x3+2] > 300) then
          begin
          flag := true;
          end
          else
          if (p2[x3]+p2[x3+1]+p2[x3+2] > 300) and (p3[x2]+p3[x2+1]+p3[x2+2] > 300) then
          begin
          flag := true;
          end;
          end;
          if (flag) then
          begin
          p1[x1]:=$ff;
          p1[x1+1]:=$ff;
          p1[x1+2]:=$ff;
          end;
        end;
      end;
    end;
    binaryBufferedImage.EndUpdate();
    binaryBufferedImage.SaveToFile('out.bmp');
end;
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行42.96875毫秒 RSS