-2

如何获得 pIplImage 中颜色的百分比(我使用 Delphi),例如图像中红色(clRed)、绿色(clGreen)、蓝色(clBlue)的百分比。

我想img.Canvas.Pixels[0, 0]用 OpenCv 模拟这个,但不知道如何逐个像素地遍历图像,但不知道如何。

例子:

procedure TForm1.Button4Click(Sender: TObject);
var i, j, r, b, g, tot : integer;
begin
  r := 0; b := 0; g := 0;
  for i := 0 to Image1.Width - 1 do
    for j := 0 to image1.Height - 1 do
      if image1.Canvas.Pixels[i,j] = clRed then
        inc(r)
      else if image1.Canvas.Pixels[i,j] = clBlue then
        inc(b)
      else if image1.Canvas.Pixels[i,j] = clGreen then
        inc(g);
    tot := Image1.Width * Image1.Height;
    showmessage('Red %:' + IntToStr(r div tot)+#13#10+
                'Green %:'+IntToStr(g div tot)+#13#10+
                'Blue %:'+IntToStr(b div tot));
end;

在我的搜索中,我发现我必须将 转换pIplImage为 Mat(使用cvMat()),然后使用 cvGet2D 将其拆分为数组以获得我猜的 4 个数组、RGB 和 Gray。但不知道下一步是什么...

var
    mat : TCvMat;
    res : TCvScalar;
begin
    object_filename := 'd:\1.bmp';
    image := cvLoadImage(pcvchar(@object_filename[1]), CV_LOAD_IMAGE_UNCHANGED);

    mat := cvMat(image.width, image.height, 0, image);
   for i := 0 to mat.rows - 1 do
     for j := 0 to mat.cols - 1 do
     begin
         res := cvGet2D(@mat, i, j);
         writeln('red: ', res.val[0]:2:2);
         writeln('green: ', res.val[1]:2:2);
         writeln('Blue: ', res.val[2]:2:2);
         writeln('Gray: ', res.val[3]:2:2);
         writeln;
    end;

    readln;
 end.

但这仅返回具有实际值的 val[0],其余均为零。

最后,使用 pIplImage 和 OpenCV 计算颜色百分比的最快方法是什么。更少的时间,mem,cpu...

4

1 回答 1

0

这是解决方案:

var
  img     : pIplImage;
  channels: array [0 .. 2] of pIplImage;
  BGRSum  : Array [0 .. 2] of TCvScalar;
  i, total: Integer;

begin
  try
    img := cvLoadImage(filename, 1);

    for i := 0 to 2 do
      channels[i] := cvCreateImage(cvGetSize(img), 8, 1);

    cvSplit(img, channels[0], channels[1], channels[2], 0);

    for i := 0 to 2 do
      BGRSum[i] := cvSum(channels[i]);

    total := img^.width * img^.height * 255;

    WriteLn('Color percentage of RGB(ex red 50%, green 25% and blue %25) in an image is');

    writeln('red:   ', BGRSum[2].val[0] / total * 100:2:2);
    writeln('green: ', BGRSum[1].val[0] / total * 100:2:2);
    writeln('blue:  ', BGRSum[0].val[0] / total * 100:2:2);

    readln;
  except
    on E: Exception do
      writeln(
        E.ClassName, ': ', E.Message);
  end;
end.

谢谢Laex

于 2013-09-12T16:27:37.570 回答