๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ก EE's DEV/์˜์ƒ์ฒ˜๋ฆฌ

[์˜์ƒ์ฒ˜๋ฆฌ] openCV2 ํžˆ์Šคํ† ๊ทธ๋žจ, ์ •๊ทœํ™”, ์ŠคํŠธ๋ ˆ์นญ, ๊ท ๋“ฑํ™”

by Danna 2017. 2. 27.
728x90
728x90

Histogram, ํžˆ์Šคํ† ๊ทธ๋žจ

์˜์ƒ ๋‚ด ๊ฐ ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜๋ฅผ ํ•จ์ˆ˜์˜ ๊ผด๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์„ ํžˆ์Šคํ† ๊ทธ๋žจ์ด๋ผ๊ณ  ํ•œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜์‹์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.


h(g)=ngโ€‹

g = ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๊ณ  ๋ฒ”์œ„๋Š” 0~255

n_g = ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๊ฐ’์ด g ์ธ ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค



h(g) ํ•จ์ˆ˜์˜ ๊ฐ’์€ ์˜์ƒ์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ž‘๊ฑฐ๋‚˜ ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ n_g ๋ฅผ ์˜์ƒ์˜ ์ „์ฒด ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜๋กœ ๋‚˜๋ˆ„๋Š” ์ •๊ทœํ™”(normalize) ๊ณผ์ •์„ ํ†ตํ•˜์—ฌ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ํ‘œํ˜„ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.



์ •๊ทœํ™”๋œ ํžˆ์Šคํ† ๊ทธ๋žจ


์ •๊ทœํ™”๋œ ํžˆ์Šคํ† ๊ทธ๋žจ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜์‹์œผ๋กœ ํ‘œํ˜„๋˜๋ฉฐ, ํŠน์ • ๊ทธ๋ ˆ์ด ์Šค์ผ€์ผ(gray scale) ๊ฐ’์ด ๋‚˜ํƒ€๋‚˜๋Š” ํ™•๋ฅ ์˜ ๊ฐœ๋…์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.



  • p(g) = ํ™•๋ฅ  ๊ฐ’, ํ™•๋ฅ ์„ ์˜๋ฏธํ•˜๋Š” p๋กœ ๋ณ€๊ฒฝ (probability)
  • N = ์˜์ƒ์˜ ์ „์ฒด ํ”ฝ์…€์˜ ๊ฐœ์ˆ˜

๊ทธ๋ ˆ์ด ์Šค์ผ€์ผ(gray scale) ๊ฐ’ ์ „์ฒด ๋ฒ”์œ„์— ๋Œ€ํ•ด ์ •๊ทœํ™”๋œ ํžˆ์Šคํ† ๊ทธ๋žจp(g) ๊ฐ’์„ ๋ชจ๋‘ ๋”ํ•˜๋ฉด 1์ด ๋œ๋‹ค.


ํžˆ์Šคํ† ๊ทธ๋žจ์„ ํ•จ์ˆ˜์˜ ๊ทธ๋ž˜ํ”„๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด x์ถ•์€ ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๊ฐ’์ด ๋˜๊ณ , y์ถ•์€ ํ•ด๋‹น ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๊ฐ’์ด ๋‚˜ํƒ€๋‚˜๋Š” ๋นˆ๋„์ˆ˜(ํ™•๋ฅ )์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.



void histogram(char* w_name, Mat img)

{

            int hist[256] = { 0, };

            double scale = 1;

            int i, j, max = 0;

            Mat canvas(256, 256, CV_8UC1, Scalar(255));

            for (i = 0; i < img.rows; i++)

                        for (j = 0; j < img.cols; j++)

                                    hist[img.at<uchar>(i, j)]++;

            for (i = 0; i < 256; i++)

                        max = hist[i] > max ? hist[i] : max;

            max += 10;

            scale = max > canvas.rows ? (double)canvas.rows / max : 1;  // ๋น„์œจ ๋งž์ถ”๊ธฐ

            for (i = 0; i < 256; i++)

            {

                        Point pt1 = Point(i, canvas.rows - (hist[i] * scale));

                        Point pt2 = Point(i, canvas.rows);

                        line(canvas, pt1, pt2, Scalar(0));  // pt1์—์„œ pt2๊นŒ์ง€ ๊ฒ€์ •์ƒ‰ ์„  ๊ทธ๋ฆฌ๊ธฐ

            }

            imshow(w_name, canvas);

}





ํžˆ์Šคํ† ๊ทธ๋žจ ์ŠคํŠธ๋ ˆ์นญ

์˜์ƒ์˜ ํžˆ์Šคํ† ๊ทธ๋žจ์ด ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ์ „ ๊ตฌ๊ฐ„์—์„œ ๊ณจ๊ณ ๋ฃจ ๋‚˜ํƒ€๋‚˜๋„๋ก ๋ณ€๊ฒฝํ•˜๋Š” ์„ ํ˜• ๋ณ€ํ™˜ ๊ธฐ๋ฒ•์„ ํžˆ์Šคํ† ๊ทธ๋žจ ์ŠคํŠธ๋ ˆ์นญ์ด๋ผ๊ณ  ํ•œ๋‹ค.


  • ๋ช…์•”๋น„๊ฐ€ ๋‚ฎ์€ ์˜์ƒ์€ ํžˆ์Šคํ† ๊ทธ๋žจ์ด ํŠน์ • ๊ตฌ๊ฐ„์— ์ง‘์ค‘๋˜์–ด ๋‚˜ํƒ€๋‚จ
  • ๋ช…์•”์˜ ์ตœ์†Œ, ์ตœ๋Œ€๊ฐ’์˜ ๋น„์œจ์„ ์ด์šฉ. ์˜์ƒ์„ ์ „์ฒด์ ์œผ๋กœ ๊ท ์ผํ•˜๊ฒŒ ๋‹น๊ฒจ์ค€๋‹ค.
  • ํžˆ์Šคํ† ๊ทธ๋žจ ์ŠคํŠธ๋ ˆ์นญ์„ ๊ฑฐ์น˜๋ฉด ์ „ ๊ตฌ๊ฐ„์—์„œ ๋‚˜ํƒ€๋‚˜๋„๋ก ๋ณ€ํ™˜๋จ

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ช…์•”๋น„๊ฐ€ ๋†’์•„์ ธ์„œ ๋ณด๊ธฐ ์ข‹์€ ์‚ฌ์ง„ ํ˜•ํƒœ๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋œ๋‹ค.






void histogramStretching(Mat img, Mat& out)

{
            int lowvalue = 255, highvalue = 0;
            int i, j;
            for (i = 0; i < img.rows; i++)
            {
                        for (j = 0; j < img.cols; j++)
                        {
                                    if (lowvalue > img.at<uchar>(i, j))
                                                lowvalue = img.at<uchar>(i, j);
                                    if (highvalue < img.at<uchar>(i, j))
                                                highvalue = img.at<uchar>(i, j);
                        }
            }
            // histogram stretching ๊ณ„์‚ฐ
            float mult = 255 / (float)(highvalue - lowvalue);
            for (i = 0; i < img.rows; i++)
            {
                        for (j = 0; j < img.cols; j++)
                                    out.at<uchar>(i, j) = (uchar)(img.at<uchar>(i, j) - lowvalue ) * mult;
            }
}



Histogram Equalization, ํžˆ์Šคํ† ๊ทธ๋žจ ๊ท ๋“ฑํ™”

ํžˆ์Šคํ† ๊ทธ๋žจ ์ŠคํŠธ๋ ˆ์นญ์€ ์˜์ƒ์˜ ํžˆ์Šคํ† ๊ทธ๋žจ์„ ์„ ํ˜•์ ์œผ๋กœ ํŽผ์ณ์ฃผ๋Š” ๋ฐฉ์‹์ด๋ผ๋ฉด, ํžˆ์Šคํ† ๊ทธ๋žจ ๊ท ๋“ฑํ™”(Equalization; ํ‰ํ™œํ™”)๋Š” ํžˆ์Šคํ† ๊ทธ๋žจ์˜ ๋ˆ„์  ๋ถ„ํฌ ํŠน์„ฑ์— ๊ทผ๊ฑฐํ•˜์—ฌ ํžˆ์Šคํ† ๊ทธ๋žจ์˜ ๋ถ„ํฌ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.





์ž…๋ ฅ์˜์ƒ(a)์„ ๋ณด๋ฉด ํžˆ์Šคํ† ๊ทธ๋žจ์ด ์ค‘์•™์—๋งŒ ๋ฐ€์ง‘๋˜์–ด ๋ˆ„์  ํ•จ์ˆ˜๊ฐ€ ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ์ค‘๊ฐ„ ๋ถ€๋ถ„์—์„œ ์ตœ๋Œ“๊ฐ’๊นŒ์ง€ ๋„๋‹ฌํ•ด ์žˆ๋‹ค.

ํžˆ์Šคํ† ๊ทธ๋žจ ๊ท ๋“ฑํ™”๊ฐ€ ์ ์šฉ๋œ (b)์˜์ƒ์€ ๋ˆ„์  ํ•จ์ˆ˜์˜ ๋ชจ์–‘์ด ์ง์„  ํ˜•ํƒœ๋กœ ๋ฐ˜๋“ฏํ•˜๊ฒŒ ์ฆ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


void histogramEqulization(Mat img, Mat& out)
{
    int i, j;
    unsigned int hist[256] = { 0, };
    float cdf[256] = { 0, };
    int pixel, max;

    for (i = 0; i < img.rows; i++)
    {
        for (j = 0; j < img.cols; j++)
        {
            hist[img.at<uchar>(i, j)]++;
        }
    }

    cdf[0] = hist[0];

    for (i = 1; i < 256; i++)
        cdf[i] = cdf[i - 1] + hist[i];

    max = cdf[255];

    for (i = 0; i < img.rows; i++)
    {
        for (j = 0; j < img.cols; j++)
        {
            pixel = cdf[img.at<uchar>(i, j)] / max * 255;
            out.at<uchar>(i, j) = (pixel > 255) ? 255 : pixel;
        }
    }
    imshow("equlization image", out);
}





  • 2020.12.07 ์ˆ˜์ •
  • ์ด๋ฏธ์ง€ ์ถœ์ฒ˜ ๋ฐ ์ฐธ๊ณ  ์‚ฌ์ดํŠธ
  • https://iskim3068.tistory.com/40


728x90
728x90