2012-02-15 2 views
-1

이미지에서 흰색 직사각형을 찾으려고합니다. 사각형 크기는 고정되어 있습니다. 이것은 내가 아직 같이 왔어요 것입니다 : 내가 필요로하는 사각형 (0;0)의 시작에 가까운 경우이미지에서 흰색 직사각형 찾기

BufferedImage bImage = bufferedImage; 
int height = bufferedImage.getHeight(); //~1100px 
int width = bufferedImage.getWidth(); //~1600px 
int neededWidth = width/2; 
int neededHeight = 150; 
int x = 0; 
int y = 0; 
boolean breaker = false; 
boolean found = false; 
int rgb = 0xFF00FF00; 
int fx, fy; 

fx = fy = 0; 
JavaLogger.log.info("width, height: " + w + ", " + h); 
while ((x != (width/2) || y != (height - neededHeight)) && found == false) { 
for (int i = y; i - y < neededHeight + 1; i++) { 
    for (int j = x; j - x < neededWidth + 1; j++) { //Vareetu buut, ka +1 vajadziigs 
     //JavaLogger.log.info("x,y: " + j + ", " + i); 
     long pixel = bImage.getRGB(j, i); 
     if (pixel != colorWhite && pixel != -1) { 
      //bImage.setRGB(j, i, rgb); 
      //JavaLogger.log.info("x,y: " + (j+x) + ", " + (i+y)); 
      breaker = true; 
      break; 

     } else { 
      //bImage.setRGB(j, i, 0xFFFFFF00); 
     } 
     //printPixelARGB(pixel); 
     if ((i - y == neededHeight-10) && j - x == neededWidth-10) { 
      JavaLogger.log.info("width, height: " + x + ", " + y + "," + j + ", " + i); 
      fx = j; 
      fy = i; 
      found = true; 
      breaker = true; 
      break; 
     } 
    } 
    if (breaker) { 
     breaker = false; 
     break; 
    } 

} 

if (x < (width/2)) { 
    x++; 
} else { 
    if (y < (height - neededHeight)) { 
     y++; 
     x = 0; 
    } else { 
     break; 
    } 
    } 
//JavaLogger.log.info("width, height: " + x + ", " + y); 
} 

if (found == true) { 

    for (int i = y; i < fy; i++) { 
     for (int j = x; j < fx; j++) { 
      bImage.setRGB(j, i, 0xFF00FF3F); 
     } 

    } 

} 
JavaLogger.log.info("width, height: " + w + ", " + h); 

이이 작품을 좋아하지만 더 멀리 얻을로, 성능이 매우 심각하게 저하됩니다. 할 수있는 일이 있다면 궁금해하니?

예를 들어,이 검색은 거의 8 초가 걸렸습니다. One of searches 나는 이것이 더 효과적으로 효과적으로 수행 될 수 있다고 생각합니다. 어떤 얼룩 발견? 그것에 대해 읽어보십시오,하지만 그것을 어떻게 적용할지 모르겠습니다.

또한 자바와 이미지 처리에 익숙하지 않으므로 도움을 받으실 수 있습니다.

+2

더 나은 도움을 받으려면 [SSCCE] (http://sscce.org/)를 게시하십시오. 1,191px × 1,684px의 이미지를 게시 할 필요가 없습니다. *** 작물에 대해 들어 보지 못했습니까 ***?!? –

+0

이것은 SSCCE입니다. 코드의 모든 부분은 문제와 관련이 있습니다. 이미지에 관해서는 - 그렇습니다. 내 문제의 범위를 표시하기 위해 전체 이미지를 넣었습니다. 이미지가 잘린다면, 바닥에 도달하는 데 오래 걸리지 않을 것입니다. 이제는 분명합니다. –

+1

* "이것은 SSCCE입니다."* 원하는만큼 큰 소리로 말하지만 사실이 아닙니다. * "코드의 모든 부분이 문제와 관련이 있습니다."* 음 ... 좋습니다. 코드를 'SC'로 만드는 데 필요한 부분은 무엇입니까? 혼란 스러울 경우, 문제는 코드의 길이가 아닙니다. 실제로 * 링크를 읽었습니까? * "내 문제의 범위를 표시하기 위해 전체 이미지를 넣었습니다."* 당신의 케이크를 가지고 그것을 먹을 수있는 하나의 영리한 속임수 (테스트 할 큰 이미지뿐만 아니라 다운로드/사용할 작은 이미지가 있음))는 포스트에 작은 이미지를 삽입 한 다음 런타임에이를 큰 이미지로 그립니다. –

답변

1

이것은 매우 거칠지 만 이미지의 모든 흰색 픽셀을 성공적으로 찾습니다. 원하는 크기이고 모든 것이 있지만 기본 사항이 있는지 확인하기 위해 더 많은 검사를 수행 할 수 있습니다.

추신 : 나는 당신의 이미지를 테스트하지 않았습니다. rthis.rc 사진 크기와 p하고 this.px는 "침식"로 알려진 조작에 의해 해결 될 수있다 요구하는 어떤 내부 사각형의 크기

public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    final int r = 100; 
    final int p = 10; 

    NewJPanel pan = new NewJPanel(r, p, new A() { 
     @Override 
     public void doImage(BufferedImage i) { 
      int o = 0; 

      for (int j = 0; j < i.getWidth() - p; j++) { 
       for (int k = 0; k < i.getHeight() - p; k++) { 

        PixelGrabber pix2 = new PixelGrabber(
          i, j, k, p, p, false); 
        try { 
         pix2.grabPixels(); 
        } catch (InterruptedException ex) {} 

        int pixelColor = pix2.getColorModel() 
          .getRGB(pix2.getPixels()); 

        Color c = new Color(pixelColor); 
        if (c.equals(Color.WHITE)) { 
         System.out.println("Found at : x:" + j + ",y:" + k); 
        } 

       } 
      } 
     } 
    }); 

    frame.getContentPane().add(pan); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(500, 500); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
} 

private interface A { 
    void doImage(BufferedImage i); 
} 

private static class NewJPanel extends JPanel { 
    private static final long serialVersionUID = -5348356640373105209L; 

    private BufferedImage image = null; 
    private int px; 
    private int rc; 
    private A a; 

    public NewJPanel(int r, int p, A a) { 
     this.px = p; 
     this.rc = r; 
     this.a = a; 
    } 

    public BufferedImage getImage() { 
     return image; 
    } 

    @Override public void paint(Graphics g) { 
     super.paint(g); 

     image = new BufferedImage(this.rc, this.rc, 
       BufferedImage.TYPE_INT_ARGB); 
     java.awt.Graphics2D g2 = image.createGraphics(); 

     g2.setColor(Color.BLACK); 
     g2.fillRect(0, 0, this.rc, this.rc); 
     g2.setColor(Color.WHITE); 
     g2.fillRect(
       new Random().nextInt(this.rc - this.px), 
       new Random().nextInt(this.rc - this.px), 
       this.px, this.px); 

     g.drawImage(image, this.rc, this.rc, this); 
     this.a.doImage(this.image); 
    } 
} 
0

저는 전문가는 아니지만 코드가 문제라고 생각하지 않습니다. 알고리즘을 변경해야합니다. 나는 반복적으로 2 차원 평면 상에 하나의 흰색 픽셀을 검색하여 시작하는 것, 뭔가 같은 :

findWhitePixel (사각형) '광장'의 중간에 픽셀에서 { 봐 -이 흰색 복귀는 달리, 만약 : findWhitePixel ('square'의 오른쪽 상단) findWhitePixel ('square'의 왼쪽 상단) findWhitePixel ('square'의 오른쪽 하단) findWhitePixel ('square'의 하단 왼쪽) }

흰색 픽셀을 발견하면 모양, 경계선을 찾기 위해 위, 아래, 왼쪽 및 오른쪽으로 트래버스를 시도해보십시오. 주어진다면 사각형 만있을 수 있습니다. 다른 모양 (삼각형, 원 등)이있는 경우 여기에서 확인이 필요합니다.

+0

알고리즘이 검색 프로세스 속도를 높이려면 어떻게해야합니까? 내가 보았 듯이 거의 모든 픽셀을 두 번 이상 지나야합니다. –

+0

흰색 직사각형의 상대적 크기에 따라 흰색 픽셀을 누르기 전에 소수의 픽셀 만 살펴볼 수 있습니다. – Rami

0

입니다. 침식은 모든 픽셀을 해당 위치 (왼쪽 위 모서리)에서 요청 된 크기의 사각형에있는 모든 픽셀 중 가장 어두운 픽셀로 바꿉니다. 여기서 가장 어두운 의미는 흰색이 아닌 흰색이 흰색을 대체한다는 것을 의미합니다.

침식 출력은 W-1 열과 H-1 행이 적은 이미지입니다. 그 안에있는 모든 흰색 픽셀은 해결책에 해당합니다.

행운의 경우 사각형 모양의 침식은 분리 가능한 작업입니다. 즉, 첫 번째 침식 결과물에서 수평 세그먼트 모양을 사용한 다음 세로 모양을 사용하여 먼저 침식 할 수 있습니다. W x H 재조정 크기의 경우, 이것은 W * H 작업을 W + H로 대체하므로 상당한 절약 효과가 있습니다.

이진 이미지 (흰색이 아닌 흰색)의 경우에도 세그먼트에 의한 침식은 매우 효율적으로 수행 할 수 있습니다. 모든 행에서 독립적으로 모든 연속적인 흰색 픽셀을 찾고 W-1 오른쪽 끝은 흰색이 아닌 것으로 바꾼다. 모든 행에 동일하게 작업하여 흰색 실행을 H-1 픽셀만큼 줄입니다.

예 : 검색 모든 3 × 2 직사각형 :

####....#### 
##.....#..## 
#..######... 
.....###.... 

3 × 침식 후 :

####..#### 
##...##### 
#########. 
...#####.. 

1 × 침식 후 :

####.##### 
########## 
#########. 

이 알고리즘에 관계없이, 화소마다 일정 시간 (소요 직사각형 크기). 제대로 구현하려면 밀리 세컨드의 시간이 필요합니다.

관련 문제