【问题标题】:Getting surrounding pixels color and change them获取周围像素的颜色并更改它们
【发布时间】:2013-04-05 14:19:32
【问题描述】:

我想制作一个应用程序,它首先检查图像的某个像素颜色。 当它找到具有正确像素颜色的像素时,它将“突出显示”该像素。

但棘手的部分来了,之后我想检查“突出显示”像素的 8 个周围像素的颜色。如果这些周围像素之一是黑色的,则该像素的颜色应该会改变。

我已经设法“突出显示”具有特定像素颜色的像素(请参见下面的代码),但我一直在寻找如何检查其周围像素的方法...

我希望我的问题很清楚。

procedure Tform_Main.analyzepixels (bitmapanalyse : TBitmap);
var
C: TColor;
X, Y:Integer;
Pixels : PRGBTripleArray 
begin
  bitmapanalyse := TBitmap.Create;
  try
  bitmapanalyse.Assign(FBitmap);

  Form_memo.Memo1.Lines.BeginUpdate;
  try
  for Y := 0 to bitmapanalyse.Height - 1 do
  begin
    Pixels := bitmapanalyse.ScanLine[Y];
    ProgressBar2.StepIt;
    ProgressBar2.Update;
    Application.ProcessMessages;
    for X := 0 to bitmapanalyse.Width - 1 do
    begin
      if (Pixels[X].rgbtRed >= Pixelcolor) and 
         (Pixels[X].rgbtGreen >= Pixelcolor) and    
         (Pixels[X].rgbtBlue >= Pixelcolor)
      then
      begin
        C := RGB(
          Pixels[X].rgbtRed,
          Pixels[X].rgbtGreen,
          Pixels[X].rgbtBlue
        );

           Form_memo.Memo1.Lines.Add(
          '===============' + sLineBreak +
          'Pixel[' + IntToStr(X) + '; ' + IntToStr(Y) + ']' + sLineBreak +
          'Color: ' + ColortoString(C))

        ;
        Pixels[X].rgbtRed := 255;
        Pixels[X].rgbtGreen := 255;
        Pixels[X].rgbtBlue := 0;
      end;
    end;
  end;
finally
  Form_memo.Memo1.Lines.EndUpdate;
end;

【问题讨论】:

    标签: delphi image-processing pixels


    【解决方案1】:

    我可能遗漏了一些东西,但既然你有 (x, y) 你可以通过简单地使用来获得所有周围的像素

    [x - 1, y - 1][x  , y - 1][x + 1, y - 1]
    [x - 1, y    ][x  , y    ][x + 1, y    ]
    [x - 1, y + 1][x  , y + 1][x + 1, y + 1]
    

    您已经有了获取特定像素的逻辑。我会重构你所拥有的

    function GetRGBAt(ABitmap: TBitmap; const X, Y: Integer) : PRGBTriple;
    begin
        Result := nil; // don't remember if this is necessary
        if (Y >= 0) and (X >= 0) then
        begin
            Result := aBitmap.ScanLine[Y];
            Inc(Result, X);
        end;
    end;
    
    function IsRGBBlack(ABitmap: TBitmap; const X, Y: Integer) : boolean;
    var
        P: PRGBTriple;
    begin
        P := GetRGBAt(ABitmap, X, Y);
        Result := (P <> nil) and 
                (P^.rgbtBlue + P^.rgbtGreen + P^.rgbtBlue = 0);
    end;
    

    然后您只需将检查添加到您的代码中。由于 Delphi 在 OR 布尔表达式上短路,因此以下内容就足够了:

    if    IsRGBBlack(bitmapanalyse, x - 1, y-1) 
       or IsRGBBlack(bitmapanalyse, x,     y-1) 
       or IsRGBBlack(bitmapanalyse, x + 1, y-1) 
    
       or IsRGBBlack(bitmapanalyse, x - 1, y) 
       // x, y not needed
       or IsRGBBlack(bitmapanalyse, x + 1, y) 
    
       or IsRGBBlack(bitmapanalyse, x - 1, y + 1) 
       or IsRGBBlack(bitmapanalyse, x,     y + 1) 
       or IsRGBBlack(bitmapanalyse, x + 1, y + 1)  then
    
    // your logic here for (x, y)
    

    这是一种极其简单的方法,但是您没有说明例如在相邻符合条件的像素的情况下要做什么,因此您可能需要为这些像素添加一些额外的逻辑。

    【讨论】:

    • Return Result 不是 Delphi 代码。 :-) 另外,PRGBTriple 没有rgbBlack 成员。 IsRGBBlack 测试可以简化为 Result := (P &lt;&gt; nil) and (P^.rgbtRed + p^.rgbtGreen + P^.rgbtBlue = 0);
    • 你是对的,我会改变它。这是所有邮件代码! (我添加了您使用 sum 的建议,但我不确定这是否更清楚)-顺便说一句,“返回结果”向您展示了当您在任何一天使用太多语言编程时会发生什么......
    • 前两个是修复建议。总和只是一种选择。 :-)
    • 哦,当然。我知道它仍然是正确的。我想我对这两种选择都没有坚定的立场,而且你的建议在肉眼看来更有效。
    猜你喜欢
    • 1970-01-01
    • 2021-11-29
    • 2013-11-25
    • 2023-01-13
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2016-02-11
    • 2012-12-06
    相关资源
    最近更新 更多