가장자리와 사각형을 감지하는 방법


14

이미지에서 직사각형을 감지하려고합니다. 이미지의 배경은 하나의 색상입니다 (대부분의 경우). 나중에 Hough Transformation을 수행하기 위해 이진 이미지 (1 = 배경, 0 = 가장자리)를 얻는 두 가지 방법을 시도했습니다 ...

  1. 소벨 또는 캐니 필터

  2. 부드러운 이미지 A, 차이 이미지 A 만들기-가우스, 임계 값으로 이진 이미지 만들기 (히스토그램 만들기, 가장 높은 빈은 배경이어야합니다 ...)

결과는 가장자리가있는 이진 이미지입니다. 다양한 이미지에 어떤 방법이 더 효과적 일지는 모르겠습니다. 어떤 아이디어?


1
"더 잘 작동합니다"는 무슨 뜻입니까? 캐니는 이런 종류의 물건에 매우 인기가 있지만 일단 가장자리가 있으면 수행하려는 작업에 따라 다릅니다. 정확히 무엇을 달성하려고합니까?
Paul R

4
커뮤니티에 대한 첫 번째 질문에 대해 새로운 사용자 투표를 중단하지 마십시오!

1
이 글타래는 유용 할 것입니다. dsp.stackexchange.com/questions/2975/…
Jim Clay

가장자리 감지기 설명 : dsp.stackexchange.com/q/74/1273
페넬로프

"결과는 가장자리가있는 이진 이미지입니다. 이제 다양한 방법으로 다양한 방법으로 어떤 방법이 더 효과적 일지는 모르겠습니다. 어떤 아이디어입니까?" 아마도 답을 찾거나 계산할 수있는 환경에서 사진을 찍으려면 이미지 테스트 라이브러리가 필요할 수 있습니다. 이 분야에 가장 적합한 알고리즘이 있다면 왜 우리는 다른 많은 것들을 배워야합니까? 나는 어떤 알고리즘이 때때로 우연히 유리하다는 장점을 가지고 있다고 생각합니다.

답변:


10

나는 한 번 사각형 감지를위한 응용 프로그램을 작성했습니다. Sobel Edge 감지와 Line Hough 변환을 사용했습니다.

Hough 이미지 (선)에서 단일 피크를 찾는 대신 프로그램은 90 도의 거리를 가진 4 개의 피크를 검색했습니다.

Hough 이미지의 각 열 (일부 각도에 해당)에 대해 로컬 최대 값에 대해 3 개의 다른 열이 검색되었습니다. 4 개의 열 각각에서 만족스러운 피크가 발견되면 사각형이 감지 된 것입니다.

이 프로그램은 사각형을 구성하고 사각형 내부 및 외부의 색상 일관성을 추가로 확인하여 오 탐지를 식별했습니다. 이 프로그램은 스캔 한 용지에서 용지 배치를 감지하기위한 것입니다.


5

Laplacian of Gaussian edge detector가 더 나은 선택임을 알 수 있습니다. 캐니 에지 디텍터보다 닫힌 컨투어를 더 자주 제공해야합니다. 다음 단계부터 Hough 변환을 적용하는 것이 목표라고 생각합니다.


2

오늘이 사이트를 방문했을 때 도움이 되겠지만 너무 늦을 수도 있습니다.

        Bitmap bmp=new Bitmap(pictureBox1.Image);
        int x1=0, x2=0, y1=0, y2=0;            
        for (int i = 1; i < bmp.Height;i++ )
        {                
            for (int j = 1; j < bmp.Width;j++ )
            {
                if( bmp.GetPixel(j,i).R<7  &&  bmp.GetPixel(j-1,i).R>240  && bmp.GetPixel(j,i-1).R>240 ){

                    for (int k = j; k < bmp.Width - 1;k++ )
                    {

                        if ((bmp.GetPixel(k, i).R < 7) && (bmp.GetPixel(k+1, i).R > 240) && (k-j>30)) {
                            int count1 = 0;

                            for (int g = j; g < k;g++ ){
                                if(bmp.GetPixel(g,i).R<7){
                                    count1++;                                    
                                }
                            }//get total width

                         if(count1==k-j){                                 
                             x1 = j;
                             y1 = i;
                             x2 = k;
                         }
                        }
                    }
                         for (int a = i; a < bmp.Height - 1;a++ )
                         {
                             if ((bmp.GetPixel(j, a).R < 7) && (bmp.GetPixel(j, a+1).R > 240) && (a- i > 30)) {

                                 int count2 = 0;

                                 for (int x = i; x < a;x++ )
                                 {
                                     if(bmp.GetPixel(j,x).R<7){                                            
                                         count2++;
                                     }
                                 }


                                 if (count2 == (a - i))
                                 {

                                     y2 = a;
                                 }
                                 else {
                                     Console.WriteLine("check");
                                 }
                             }

                         }

                         if ((bmp.GetPixel(x2, y2).R < 7) && (bmp.GetPixel(x2 + 1, y2).R > 240) && (bmp.GetPixel(x2, y2+1).R > 240))
                         {

                             bool r1 = false;
                             bool r2 = false;
                             int count3 = 0;
                             for (int y = y1; y < y2;y++ )
                             {
                                 if(bmp.GetPixel(x2,y).R<7){
                                     count3++;                                     
                                 }
                             }

                             if (count3== y2 - y1) {
                                 r1 = true;
                             }                                
                             if(r1==true){
                                 int count4=0;
                                 for (int x = x1; x < x2;x++ )
                                 {
                                     if(bmp.GetPixel(x,y1).R<7){
                                         count4++;
                                     }
                                 }

                                 if(count4==x2-x1){
                                     r2 = true;
                                     Console.WriteLine("values :  X1 " + x1 + "   y1 :" + y1 + "   width : " + (x2 - x1) + "  height :  " + (y2 - y1));
                                     Pen pen = new Pen(Color.Red, 2);
                                     pictureBox1.CreateGraphics().DrawRectangle(pen, x1, y1, x2 - x1, y2 - y1);
                                 }                     
                             }
                            }

                }

                    }// initial point loop




                }// first if

2
dsp.stackexchange에 오신 것을 환영합니다 :) 어떤 답변이라도 늦게도 매우 환영하지만 답변에 컨텍스트를 제공하면 좋을 것입니다. 설명출처 를 제공하는 답변 이 선호됩니다. 답변을 수정하고 코드의 기능과 요청한 문제에 어떻게 도움이 될지에 대한 몇 문장을 작성하고 그렇지 않은 경우 출처를 인용 할 수 있습니까? 대답이 훨씬 나아질 것입니다. 또한, 당신의 식별을 편집하십시오-시도했지만 코드의 3 분의 1을 거친 후에 길을 잃었습니다.
penelope

0

이미지가 비교적 깨끗하다면, 많은 끊김없이 명확한 사각형이 있습니다. 허프 변환의 대안은 윤곽선을 만들고 사각형이 4면 윤곽선을 형성 할 때까지 축소하는 것입니다.

이를 위해 opencv 샘플이 있습니다


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.