λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’‘ EE's DEV/μ˜μƒμ²˜λ¦¬

[μ˜μƒμ²˜λ¦¬] openCV2 이진화 νŠΈλž™λ°”, λͺ¨ν΄λ‘œμ§€ - 침식 팽창 μ—΄λ¦Ό λ‹«νž˜ μ—°μ‚°

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

Binarization, μ΄μ§„ν™”

threshold 값을 μ •ν•œ ν›„, ν•œμͺ½μ€ 0으둜 λ‹€λ₯Έ ν•œμͺ½μ€ 1 λ˜λŠ” 255둜 λ°”κΎΈλŠ” μž‘μ—…





이진화 νŠΈλž™λ°” μ„€μ •

void binaryzationTrackbar(int, void*)
{
    out2 = out1.clone();

    for (int y = 0; y < out2.size().height; y++)
    {
        for (int x = 0; x < out2.size().width; x++)
        {
            if (out2.at<uchar>(y, x) >= value)
                out2.at<uchar>(y, x) = 255;
            else
                out2.at<uchar>(y, x) = 0;
        }
    }
    imshow("edgeBinarization", out2);
}


Morphology, λͺ¨ν΄λ‘œμ§€

μ˜μƒ λ‚΄ 각 밝은 μ˜μ—­μ΄λ‚˜ μ–΄λ‘μš΄ μ˜μ—­μ„ μΆ•μ†Œ, ν™•λŒ€ν•˜λŠ” 기법
이진화 기법을 μ‚¬μš©ν–ˆμ„ λ•Œ κ²°κ³Ό μ˜μƒμ—μ„œ 흰색 μ˜μ—­μ΄λ‚˜ 검은색 μ˜μ—­μ΄ μ›ν•˜λŠ” μ˜λ„λ³΄λ‹€ λ„“κ±°λ‚˜ 쒁게 μ–»μ–΄μ‘Œμ„ κ²½μš°μ— μ‚¬μš©ν•œλ‹€.




λͺ¨ν΄λ‘œμ§€μ˜ μ’…λ₯˜λŠ” μ•„λž˜μ™€ κ°™λ‹€.
1 λŒ€μƒ μ˜μ—­μ΄ μ’μ•„μ§€λŠ” 침식 μ—°μ‚°     
2 λŒ€μƒ μ˜μ—­μ΄ λ„“μ–΄μ§€λŠ” 팽창 μ—°μ‚°     
3 λŒ€μƒ μ˜μ—­μ—μ„œ μ„ΈλΆ€ μ˜μ—­μ΄ μ œκ±°λ˜λŠ” μ—΄λ¦Ό μ—°μ‚°     
4 λΉˆν‹ˆμ΄ μ±„μ›Œμ§€λŠ” λ‹«νž˜ μ—°μ‚°
( λŒ€μƒ μ˜μ—­ = 이진 μ˜μƒμ˜ 흰색, 흑백 μ˜μƒμ˜ 밝은 μ˜μ—­ )


Erosion, 침식

침식은 μž…λ ₯ν•œ 이진 μ˜μƒμ˜ 각 픽셀에 마슀크λ₯Ό λ†“μ•˜μ„ λ•Œ,λ§ˆμŠ€ν¬κ°€ 255값을 κ°€μ§€λŠ” λͺ¨λ“  ν”½μ…€ μœ„μΉ˜μ— λŒ€ν•˜μ—¬ μž…λ ₯ μ˜μƒλ„ 255 값을 κ°€μ Έμ•Όλ§Œ 결과값이 255κ°€ λ˜λŠ” 연산이닀.
λ§Œμ•½ λŒ€μƒ μœ„μΉ˜μ—μ„œ ν•œ 픽셀이라도 0값을 가지면 결과값은 0이 되기 λ•Œλ¬Έμ— μ „μ²΄μ μœΌλ‘œ 255값을 κ°€μ§€λŠ” μ˜μ—­μ΄ μ€„μ–΄λ“œλŠ” κ²°κ³Όκ°€ λ‚˜νƒ€λ‚œλ‹€.


에지 κ²€μΆœ -> 이진화 -> 침식연산 3x3 μ‚¬κ°ν˜• ꡬ쑰의 ν•„ν„°λ₯Ό μ‚¬μš©ν•΄λ³΄μž.




void erode(Mat src, Mat& dst)
{
    dst = src.clone();

    for (int y = 1; y < src.size().height - 1; y++)
    {
        for (int x = 1; x < src.size().width - 1; x++)
        {
            if (src.at<uchar>(y, x) != 0)
            {
// μ£Όλ³€ ν”½μ…€ 쀑 ν•˜λ‚˜λΌλ„ 0인 경우, dst ν”½μ…€μ„ 0 으둜 ν•œλ‹€. 
                if (src.at<uchar>(y - 1, x - 1) == 0 || src.at<uchar>(y - 1, x) == 0 || src.at<uchar>(y - 1, x + 1) == 0 ||
                    src.at<uchar>(y, x - 1) == 0 || src.at<uchar>(y, x + 1) == 0 || src.at<uchar>(y + 1, x - 1) == 0 || src.at<uchar>(y + 1, x) == 0 || src.at<uchar>(y+1, x+1) == 0)
                    dst.at<uchar>(y, x) = 0;
            }
        }
    }
}



Dilation, 팽창

팽창 연산은 침식 μ—°μ‚°κ³Ό λ°˜λŒ€λ‘œ 마슀크의 유효 μ˜μ—­μ— μžˆλŠ” 픽셀듀을 λͺ¨λ‘ 밝게 λ§Œλ“œλŠ” 역할을 ν•œλ‹€
에지 κ²€μΆœ -> 이진화 -> 팽창 μ—°μ‚° 3x3 μ‚¬κ°ν˜• ꡬ쑰의 ν•„ν„°λ₯Ό μ‚¬μš©ν•΄λ³΄μž.



void dilate(Mat src, Mat& dst)
{
    dst = src.clone();

    for (int y = 1; y < src.size().height - 1; y++)
    {
        for (int x = 1; x < src.size().width - 1; x++)
        {
            if (src.at<uchar>(y, x) != 255)
            {
// μ£Όλ³€ ν”½μ…€ 쀑 ν•˜λ‚˜λΌλ„ 255라면, dst 픽셀을 255 둜 λ§Œλ“ λ‹€.
                if (src.at<uchar>(y - 1, x - 1) == 255 || src.at<uchar>(y - 1, x) == 255 || src.at<uchar>(y - 1, x + 1) == 255 ||
                    src.at<uchar>(y, x - 1) == 255 || src.at<uchar>(y, x + 1) == 255 || src.at<uchar>(y + 1, x - 1) == 255 || src.at<uchar>(y + 1, x) == 255 || src.at<uchar>(y + 1, x + 1) == 255)
                    dst.at<uchar>(y, x) = 255;
            }
        }
    }
}



이진 μ˜μƒμ˜ μ—΄λ¦Όκ³Ό λ‹«νž˜ μ—°μ‚°

μ—΄λ¦Όκ³Ό λ‹«νž˜ 연산은 침식과 νŒ½μ°½μ„ κ²°ν•©ν•œ ν˜•νƒœλ‘œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

μ—΄λ¦Ό 연산은 밝은 μ˜μ—­μ— λ‚˜νƒ€λ‚œ μž‘μ€ λ…Έμ΄μ¦ˆλ“€μ„ μ œκ±°ν•˜λŠ”λ° μ‚¬μš©ν•œλ‹€.λ¨Όμ € 침식 연산을 μˆ˜ν–‰ν•˜μ—¬ 밝은 μ˜μ—­μ„ μ „μ²΄μ μœΌλ‘œ μΆ•μ†Œν•œ λ‹€μŒ 팽창 연산을 뒀이어 μˆ˜ν–‰ν•˜μ—¬ 전체적인 넓이λ₯Ό μ›λž˜λŒ€λ‘œ λ³΅κ΅¬ν•œλ‹€.

λ‹«νž˜ 연산은 밝은 μ˜μ—­μ— 생긴 λ―Έμ„Έν•œ ν‹ˆμ„ λ©”μš°λŠ” 역할을 ν•œλ‹€.λ¨Όμ € 팽창 연산을 μˆ˜ν–‰ν•˜μ—¬ 밝은 μ˜μ—­μ„ λ„“νžˆκ³  ν‹ˆμƒˆλ₯Ό λ©”κΎΌλ‹€ κ·Έ 후에 λ‹€μ‹œ 침식 연산을 μˆ˜ν–‰ν•œλ‹€. 





λͺ¨ν΄λ‘œμ§€ 기법을 μ‘μš©ν•œ 객체의 μ™Έκ³½μ„  κ²€μΆœ

원본 μ˜μƒμ—μ„œ 침식 연산을 μˆ˜ν–‰ν•œ κ²°κ³Ό μ˜μƒμ„ λΉΌκΈ° 연산을 μˆ˜ν–‰ν•΄λ³΄μž.  λ‹€μŒ μˆ˜μ‹μ—μ„œ 원본 μ˜μƒ = A, 침식 연산을 μˆ˜ν–‰ν•œ κ²°κ³Ό μ˜μƒ = B 이닀.






  • 2020.12.07 μˆ˜μ • (2018 κ²¨μšΈμ— μ œμž‘ν•œ 동아리 μ„Έλ―Έλ‚˜ 자료λ₯Ό 기반으둜)


728x90
728x90