2012-08-24 34 views
9

Hiện tại tôi đang phát triển dự án xử lý hình ảnh và tôi đang sử dụng javacv để phát triển các thành phần xử lý hình ảnh. Tôi đã có thể trích xuất một số phần thú vị của một hình ảnh và bây giờ tôi cần phải đọc các tọa độ x và y của các đối tượng đó. Đây là hình ảnh mà tôi haveextractedLàm thế nào để có được tọa độ x, y của các đối tượng được trích xuất trong javacv?

enter image description here

Và tôi cần phải xác định những đối tượng và vẽ hình vuông xung quanh các đối tượng. Tôi đã đi qua một số hướng dẫn và cố gắng xác định các đối tượng bằng cách sử dụng mã sau đây.

IplImage img="sourceimage"; 
    CvSize sz = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(sz, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY); 


    CvMemStorage mem = CvMemStorage.create(); 
    CvSeq contours = new CvSeq(); 
    CvSeq ptr = new CvSeq(); 
    cvFindContours(gry, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

    CvRect boundbox; 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 
     boundbox = cvBoundingRect(ptr, 0); 
     if(boundbox.height()>10||boundbox.height()>10){ 
      cvRectangle(gry, cvPoint(boundbox.x(), boundbox.y()), cvPoint(boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0); 
      System.out.println(boundbox.x()+", "+boundbox.y()); 
     } 
    } 
    cvShowImage("contures", gry); 
    cvWaitKey(0); 

Nhưng nó không vẽ như hình chữ nhật xung quanh các đối tượng. Tôi muốn biết liệu tôi có thể sử dụng phương thức cvFindContours để xác định các đối tượng đó không? Xin vui lòng một số người có thể giải thích làm thế nào để lưu trữ mục tiêu của tôi bằng cách sử dụng javacv/opencv?

+0

Vì vậy, khi bạn vẽ các hình chữ nhật này, chúng có liên quan như thế nào với các đối tượng bạn có? – MahdeTo

+0

Tại sao bỏ qua câu trả lời cho câu hỏi của bạn ?? – ArtemStorozhuk

+0

@MahdeĐể tôi cần biết cách vẽ hình chữ nhật quanh các đối tượng này. –

Trả lời

11

Hãy thử đi qua mã sau và nó sẽ trả lời cho câu hỏi của bạn.

IplImage img=cvLoadImage("pathtosourceimage"); 
    CvSize cvSize = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(cvSize, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY); 
    cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5); 

    CvMemStorage storage = CvMemStorage.create(); 
    CvSeq contours = new CvContour(null); 

    int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0)); 

    CvSeq ptr = new CvSeq(); 

    int count =1; 
    CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0); 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 

     CvScalar color = CvScalar.BLUE; 
     CvRect sq = cvBoundingRect(ptr, 0); 

      System.out.println("Contour No ="+count); 
      System.out.println("X ="+ sq.x()+" Y="+ sq.y()); 
      System.out.println("Height ="+sq.height()+" Width ="+sq.width()); 
      System.out.println(""); 

      p1.x(sq.x()); 
      p2.x(sq.x()+sq.width()); 
      p1.y(sq.y()); 
      p2.y(sq.y()+sq.height()); 
      cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0); 
      cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0)); 
      count++; 

    } 

    cvShowImage("contures",img); 
    cvWaitKey(0); 

Đây là đầu ra mà tôi có cho hình ảnh đã cho của bạn.

enter image description here

4

cvFindContours là giải pháp phù hợp cho vấn đề của bạn.
Và tôi đã xác minh rằng nó hoạt động trên hình ảnh của bạn.
Here is my experiment

Bạn có System.out.println bên trong, đầu ra là gì?

cvFindContours có thể khó sử dụng, tôi đã gói nó vào một more general C++ function. Ngoài ra tôi sử dụng một class called vBlob để mô tả một đối tượng cvFindContours phát hiện. Từ những gì tôi thấy từ mã java của bạn, java version API rất giống với phiên bản C/C++. Vì vậy, sẽ không khó để viết lại nó.

ps. Astor đưa ra câu trả lời đúng.

4

Bạn có biết rằng findContours chức năng tìm thấy trắng đường viền trên đen nền?

Chỉ cần làm bitwise_not (hoặc tương tự trong JavaCV) cho hình ảnh của bạn và sau này áp dụng findContours. Điều này thực sự khắc phục được sự cố của bạn.

4

Không cần thư viện của bên thứ ba! gì bạn đang tìm kiếm có thể đạt được trong OpenCV sử dụng một kỹ thuật gọi là bounding box:

enter image description here

Bí quyết là sử dụng cvFindContours() để lấy những đường nét và sau đó cvApproxPoly() để cải thiện kết quả. Lưu ý rằng bạn sẽ phải đảo ngược màu của hình ảnh đầu vào bằng cách sử dụng cvNot() vì tìm kiếm cvFindContours() cho các đường viền trắng màu trắng.

  • Có giới thiệu thú vị về đường nét trong this post.
  • Có một Java demo triển khai phiên bản của hộp giới hạn để phát hiện biển số xe ô tô.

Bằng cách này cvMinEnclosingCircle() trả về trung tâm của vòng tròn là CvPoint2D32f.

+0

Bạn đã đọc mã từ câu hỏi và thực sự là câu hỏi? Anh ta đã biết cách tìm hộp giới hạn. Và làm thế nào để 'approxPoly' cải thiện kết quả trong tình huống này? Vấn đề là topicstarter không hiểu tại sao anh ta nhận được 1 hình chữ nhật thay vì 4. Và tôi đã giải thích tại sao. – ArtemStorozhuk

+1

@Astor, bạn không nên tranh luận với karlphillip, ít nhất là lịch sự, nếu không vì một lý do tốt hơn. Bạn biết đấy, bạn luôn luôn nên tôn trọng người lớn tuổi của bạn. Và anh ấy là người cao tuổi ở đây, trên thẻ opencv;) Nó giống như nói với Jon Skeet mã của anh ta không biên dịch – Sam

2

Tôi đang sử dụng C++ api nhưng tôi nghĩ cũng nên có một số chức năng trong javacv có tên drawContours hoặc cvDrawContours sử dụng đầu ra của findContours.

+0

Nhưng đầu ra của findContours là toàn bộ hình ảnh. – ArtemStorozhuk

Các vấn đề liên quan