Извлечь область круга из изображения в EMGUCV C # - PullRequest
0 голосов
/ 23 июня 2019

Я использую: Emgucv 4.0.1 Opencv 4.1.0

У меня обнаружена серия кругов с функцией HoughCircles, которые мне нужно анализировать по одному.Мне нужно посчитать, сколько цвета находится в скругленном зеленом круге, поэтому мне нужно извлечь только изображение круга, но я знаю, как извлечь только прямоугольник, который содержит гораздо больше пикселей, чем круг.Как извлечь только изображение внутри зеленой зоны?См. Изображения в ссылке ниже.

1) Исходное изображение

2) В штучной упаковке изображение получено с большим количеством пикселей, чем я хочу

3) Изображение, которое я хотел бы извлечь

// m_ListCircles = list from HoughCircles() circles coordinates.
// cell = cell number to extract.
// pictureBox1 = main picturebox with all circles detected.
// pictureBoxROI = picturebox destination single circles cutted.

int id = (int)m_ListCircles[0 + cell ];
int x = (int)m_ListCircles[1 + cell ];
int y = (int)m_ListCircles[2 + cell ];
int r = (int)m_ListCircles[3 + cell ]; // radius

// box area around the circle
int X0 = x;
int Y0 = y;
int X1 = x + r * 2;
int Y1 = y + r * 2;

// area to copy
int wid = Math.Abs(X0 - X1);
int hgt = Math.Abs(Y0 - Y1);

if ((wid < 1) || (hgt < 1)) return;

// create a rectangle are to copy
Rectangle source_rectangle = new Rectangle(Math.Min(X0, X1),Math.Min(Y0,Y1), wid, hgt);

// assign the area copied to image var
var image = new Image<Bgr, byte>(new Bitmap(pictureBox1.Image));

image.ROI = source_rectangle;

// show image
pictureBoxROI.Image = image.Bitmap;
pictureBoxROI.Refresh();

/*
// tried this but result is always a black image.
Point xyCell = new Point();
xyCell.X = X0;
xyCell.Y = Y0;

Image<Gray, byte> mask = new Image<Gray, byte>(image.Width, image.Height);
CvInvoke.Circle(mask, xyCella, r, new MCvScalar(255, 255, 255), -1, 
LineType.AntiAlias, 0);
Image<Bgr, byte> dest = new Image<Bgr, byte>(image.Width, image.Height);
dest = image.And(image, mask);

pictureBoxROI.Image = dest.Bitmap;
pictureBoxROI.Refresh();
*/

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Вы всегда можете создавать маски ROI из найденных кругов и анализировать подобные изображения

Пользовательский ROI - показывает, как использовать маску

1 голос
/ 25 июня 2019

Вы можете иметь только прямоугольные изображения. Однако после обрезки прямоугольника вы можете установить все пиксели за пределами круга прозрачными.
Вы можете определить, какие пиксели находятся за пределами круга, вычислив их расстояние от центральной точки вашего изображения с помощью пифагора. Конечно, это очень медленно, так как вы должны зациклить все пиксели, но при низком количестве пикселей это достаточно быстро.

try
{
    Image rectCroppedImage = originalImage.Clone(CropRect, originalImage.PixelFormat);
    double r = rectCroppedImage.Height; // because you are centered on your circle

    Bitmap img = new Bitmap(rectCroppedImage);

    for (int x = 0; x < img.Width; x++)
    {
        for (int y = 0; y < img.Height; y++)
        {
            // offset to center
            int virtX = x - img.Width / 2;
            int virtY = y - img.Height / 2;

            if (Math.Sqrt(virtX * virtX + virtY * virtY) > r)
            {
                img.SetPixel(x, y, Color.Transparent);
            }
        }
    }
    return img; // your circle cropped image
}
catch (Exception ex)
{
}

Этого также можно добиться с помощью маски и «умножения» вашего изображения белым кружком. Такого можно достичь, например, с помощью волшебства изображения. Вы можете найти пакет ImageMagick NuGet здесь: https://github.com/dlemstra/Magick.NET

...