Создание точки в центре растрового изображения C # - PullRequest
0 голосов
/ 08 мая 2018

Я пытался найти это, но я не могу найти какой-либо код для работы с растровым изображением или PNG. Я делаю некоторые вычисления, чтобы найти центр группы черных точек на бинаризованном изображении. Я хочу знать, является ли центр правильным, рисуя красную точку в центральных точках. Все графические методы, которые я использовал, рисуют красную точку на форме, а не на самом сохраненном изображении. Как я могу нарисовать красную точку на бинаризованном изображении? (Binarized в основном означает применение порога к изображению, чтобы получить, где свет). Я приложу свой код ниже. В основном я нажимаю кнопку, и затем происходит некоторый алгоритм оттенков серого, затем я применяю порог Бернсена и сохраняю это изображение как «результат». Затем я перехожу на результат изображения и делаю свои расчеты. Я хочу нарисовать красную точку с XCenter и YCenter в результате.

    //Function for going through the image in windows of 2 pixels
    private ArrayList getNeighbours(int xPos, int yPos, Bitmap bitmap)
    {
        ArrayList neighboursList = new ArrayList();

        int xStart, yStart, xFinish, yFinish;

        int pixel;

        xStart = xPos - 2;
        yStart = yPos - 2;

        xFinish = xPos + 2;
        yFinish = yPos + 2;


        for (int y = yStart; y <= yFinish; y++)
        {
            for (int x = xStart; x <= xFinish; x++)
            {

                if (x < 0 || y < 0 || x > (bitmap.Width - 1) || y > (bitmap.Height - 1))
                {
                    continue;
                }
                else
                {
                    pixel = bitmap.GetPixel(x, y).R;

                    neighboursList.Add(pixel);
                }
            }
        }

        return neighboursList;
    }


 private void button5_Click_1(object sender, EventArgs e)
    {
        for (int i = 48; i < 49; i++)
        {
            BlackPoints = 0;
            SumX = 0;
            SumY = 0;
            Xcenter = 0;
            Ycenter = 0;

            pictureBox2.Image = System.Drawing.Image.FromFile(@"C:\Users\Salma\Desktop\Images\" + i + ".png");
            Bitmap image = new Bitmap(pictureBox2.Image);


            /////////////Gray Scale First////////////////////
            byte red, green, blue, grayscale;

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    red = image.GetPixel(x, y).R;
                    green = image.GetPixel(x, y).G;
                    blue = image.GetPixel(x, y).B;

                    grayscale = Convert.ToByte((red + green + blue) / 3);
                    image.SetPixel(x, y, Color.FromArgb(grayscale, grayscale, grayscale));
                }

            }
            //////////////////////////////////////////////
            //////////////Bernsen Threshold///////////////
            Bitmap result = new Bitmap(pictureBox2.Image);

            int iMin, iMax, t, c, contrastThreshold, pixel;

            contrastThreshold = 110;

            ArrayList list = new ArrayList();

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    list.Clear();

                    pixel = image.GetPixel(x, y).R;
                    list = getNeighbours(x, y, image);
                    list.Sort();

                    iMin = Convert.ToByte(list[0]);
                    iMax = Convert.ToByte(list[list.Count - 1]);

                    t = ((iMax + iMin) / 2);

                    c = (iMax - iMin);

                    if (c < contrastThreshold)
                    {
                        pixel = ((t >= 160) ? 0 : 255);
                    }
                    else
                    {
                        pixel = ((pixel >= t) ? 0 : 255);
                    }
                    result.SetPixel(x, y, Color.FromArgb(pixel, pixel, pixel));

                }

            }

            pictureBox3.Image = result;
            result.Save("C:\\Users\\Salma\\Desktop\\Threshold\\" + i + ".png");

            for (int h = 0; h < result.Height; h++)
            {
                for (int w = 0; w < result.Width; w++)
                {
                    //Get the color at each pixel
                    Color now_color = result.GetPixel(w, h);

                    //Compare Pixel's Color ARGB property with the picked color's ARGB Property 
                    if (now_color.ToArgb() == Color.Black.ToArgb())
                    {

                        SumX += w;
                        SumY += h;

                        BlackPoints++;


                        Xcenter = SumX / BlackPoints;
                        Ycenter = SumY / BlackPoints;



                    }
                }
            }

        }
    }

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

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

Как нарисовать красную точку на бинаризованном изображении?

Это реализация того, как вы можете нарисовать круг на изображении.

Бедно, но работает.

public void DrawCircl(Point index, Bitmap img,int Radius) 
{
    for (int i = 0; i < 360; i++)
    {
        double x = index.X - Radius * Math.Cos(2 * Math.PI / 360 * i);
        double y = index.Y - Radius * Math.Sin(2 * Math.PI / 360 * i);
        img.SetPixel((int)x, (int)y, Color.Red);
    }
}



//This is your image from the pictureBox1
Bitmap img = new Bitmap(pictureBox1.Image);

// I am targeting the middle of the image, Your case would be the binarized image
Point index = new Point(img.Size.Width / 2, img.Size.Height / 2);

// Calling Draw Cirle Method, the last parameter is the radius.
DrawCircl(index,img,40);

// After the circle been drawn you save the image where you want
img.Save(@"[Path to Save IMG]");
0 голосов
/ 08 мая 2018

Я думаю, что ошибка в расчете центра. Для одного вы делаете Xcenter = SumX / BlackPoints; и Ycenter = SumY / BlackPoints; в цикле. Есть также много других вопросов, таких как:

Последовательные назначения

bool flag = false;
flag = true;

или

ArrayList list = new ArrayList();
    // inside the loop
    list = getNeighbours(x, y, image);

и Ненужные множественные вызовы медленных функций

red = image.GetPixel(x, y).R;
green = image.GetPixel(x, y).G;
blue = image.GetPixel(x, y).B;

Также Использование ArrayList вместо рекомендуемого List<byte> или любого другого типа, возвращаемого getNeighbours().


Я позволил себе попытаться немного очистить код:

private void button_Click(object sender, EventArgs e)
{
    GrayScaleFirst();
    BernsenThreshold();
    if(GetBlackPixelCenter(out int xc, out int yc))
    {
         // use xc, yc
    }
}

void GrayScaleFirst()
{
    /////////////Gray Scale First////////////////////
    byte grayscale;
    Bitmap image=new Bitmap(pictureBox1.Image);            
    if(image==null)
    {
        return;
    }
    for(int y=0; y<image.Height; y++)
    {
        for(int x=0; x<image.Width; x++)
        {
            Color color=image.GetPixel(x, y);
            grayscale=Convert.ToByte((color.R+color.G+color.B)/3);
            image.SetPixel(x, y, Color.FromArgb(grayscale, grayscale, grayscale));
        }
    }
    pictureBox1.Image=image;

}

void BernsenThreshold()
{
    Bitmap gray=pictureBox1.Image as Bitmap;
    Bitmap image=new Bitmap(pictureBox1.Image);

    int iMin, iMax, t, c, contrastThreshold, pixel;

    contrastThreshold=110;

    for(int y=0; y<image.Height; y++)
    {
        for(int x=0; x<image.Width; x++)
        {

            Color color=gray.GetPixel(x, y);
            pixel=color.R;
            var list=GetNeighboursSorted(x, y, image);

            iMin=list[0];
            iMax=list[list.Count-1];

            t=((iMax+iMin)/2);

            c=(iMax-iMin);

            if(c<contrastThreshold)
            {
                pixel=((t>=160)?0:255);
            }
            else
            {
                pixel=((pixel>=t)?0:255);
            }
            image.SetPixel(x, y, Color.FromArgb(pixel, pixel, pixel));

        }
    }
    pictureBox1.Image=image;

}

bool GetBlackPixelCenter(out int x_center, out int y_center)
{
    Bitmap image=pictureBox1.Image as Bitmap;

    int black=Color.Black.ToArgb();

    x_center=0; y_center=0;
    int count = 0;
    for(int h=0; h<image.Height; h++)
    {
        for(int w=0; w<image.Width; w++)
        {
            //Get the color at each pixel
            Color now_color=image.GetPixel(w, h);

            //Compare Pixel's Color ARGB property with the picked color's ARGB Property 
            if(now_color.ToArgb()==black)
            {
                x_center+=w;
                y_center+=h;
                count++;
            }
        }
    }

    x_center=count>0?x_center/count:0;
    y_center=count>0?y_center/count:0;

    return count>0;
}

static List<byte> GetNeighboursSorted(int x, int y, Bitmap image)
{
    var list=new List<byte>();

    int i1=Math.Max(0, y-1), i2=Math.Min(y+1, image.Height-1);
    int j1=Math.Max(0, x-1), j2=Math.Min(x+1, image.Width-1);

    for(int i=i1; i<=i2; i++)
    {
        for(int j=j1; j<=j2; j++)
        {
            if(i!=y && j!=x) 
            {
                list.Add( Convert.ToByte(image.GetPixel(j, i).GetBrightness()*255));
            }
        }
    }

    list.Sort();
    return list;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...