2011-12-21 46 views
12

Như một loại "dự án nghỉ" tôi đang chơi xung quanh với OpenCV và muốn phát hiện và đo lường nội dung.OpenCV C++/Obj-C: Phát hiện đối tượng thích hợp

công việc hiện tại (giai đoạn đầu - phát hiện):

  1. Chuyển đổi sang dạng grayscale (cv :: cvtColor)
  2. Apply ngưỡng thích nghi (cv :: adaptiveThreshold)
  3. Áp dụng phát hiện cạnh khôn ngoan (cv: : Canny)
  4. đường nét Tìm (cv :: findContours)

kết quả của tôi là kinda crappy và tôi không chắc chắn là những gì righ t hướng đi. Tôi đã có cvBlob làm việc theo thiết lập hiện tại của tôi (OSX 10.7.2, Xcode 4.2.1) là một cách tốt hơn để đi? Nếu vậy, làm thế nào tôi có thể thực hiện nó đúng cách?

Hoặc tôi có cần trừ số liệu nền trước không? Tôi cố gắng đó nhưng đã không thể tìm thấy đường nét sau

Dưới đây là hình ảnh của tôi: image to measure

Và đó là đầu ra của tôi, khi tôi vẽ đường viền của tôi trở lại thành hình ảnh đầu tiên: output

CẬP NHẬT

Tôi nhận được nó hoạt động trong chương trình của tôi và đầu ra của tôi trông hơi khác một chút ...

- (IBAction)processImage:(id)sender 
{ 
    cv::Mat forground = [[_inputView image] CVMat]; 
    cv::Mat result = [self isolateBackground:forground]; 
    [_outputView setImage:[NSImage imageWithCVMat:result]]; 
} 

- (cv::Mat)isolateBackground:(cv::Mat &)_image 
{ 
    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0; 
    cv::cvtColor(_image, _image, CV_RGB2HSV_FULL); 
    cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); 
    cv::Mat bgIsolation; 
    cv::inRange(_image, cv::Scalar(bl, gl, rl), cv::Scalar(bh, gh, rh), bgIsolation); 
    bitwise_not(bgIsolation, bgIsolation); 
    erode(bgIsolation, bgIsolation, cv::Mat()); 
    dilate(bgIsolation, bgIsolation, element); 
    return bgIsolation; 
} 

Trả lời

10

Đây có thể là loại một hack, nhưng vì đó là một "dự án kỳ nghỉ", tôi sẽ đăng nó anyway :)

Các bạn đã thử cô lập nền và sau đó đảo ngược mặt nạ (điều này sẽ giả định bất cứ điều gì không nền là một đối tượng, nhưng nó có thể làm việc cho những gì bạn muốn).

Dưới đây là kết quả tôi đã sử dụng chức năng OpenCV inRange: enter image description here

Bạn có thể muốn làm mịn hình ảnh (pre-process) với GuassianBlur để thoát khỏi một số các jagginess. Tôi đã sử dụng hạt nhân giãn nở lớn hơn hạt nhân xói mòn (5x5 so với 3x3) để loại bỏ một số điểm ảnh nhiễu. Việc làm mịn có thể giúp điều này cũng tinh chỉnh các ngưỡng có thể làm cho sự xói mòn không cần thiết. Nhưng, điều đó sẽ giúp bạn bắt đầu.

Cuối cùng, đây là nhanh chóng ít đoạn mã của tôi, tôi sử dụng để tìm phạm vi này:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <vector> 

using namespace cv; 
using namespace std; 

int main(int argc, char** argv) 
{ 
    Mat src = imread("test.jpg"); 


    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0; 

    string windowName = "background"; 
    namedWindow(windowName); 

    createTrackbar("rh", windowName, &rh, 255); 
    createTrackbar("rl", windowName, &rl, 255); 
    createTrackbar("gh", windowName, &gh, 255); 
    createTrackbar("gl", windowName, &gl, 255); 
    createTrackbar("bh", windowName, &bh, 255); 
    createTrackbar("bl", windowName, &bl, 255); 

    // for dilation 
    Mat element = getStructuringElement(MORPH_RECT, Size(5, 5)); 

    Mat bgIsolation; 
    int key = 0; 
    do 
    { 
     inRange(src, Scalar(bl, gl, rl), Scalar(bh, gh, rh), bgIsolation); 

     bitwise_not(bgIsolation, bgIsolation); 

     erode(bgIsolation, bgIsolation, Mat()); 
     dilate(bgIsolation, bgIsolation, element); 

     imshow(windowName, bgIsolation); 
     key = waitKey(33); 
    } while((char)key != 27); 

    waitKey(); 

    return 0; 
} 

Thưởng thức các dự án kỳ nghỉ! Trông vui vẻ :)

+0

Cảm ơn rất nhiều! Bạn có thể xem mã của tôi không? – dom

+0

@moosgummi Lý do bạn nhận được một đầu ra khác nhau là vì bạn đang chuyển sang không gian màu HSV. Ngưỡng của tôi là dành cho không gian RGB. Bạn có thể sử dụng HSV, nhưng bạn sẽ cần phải tìm các phạm vi thích hợp cho không gian đó. Bạn có thể thêm chuyển đổi màu đó vào ứng dụng mẫu của tôi và thử nó. Tôi tưởng tượng bạn sẽ chỉ cần lo lắng về các kênh Hue và Saturation vì kênh Value không chứa bất kỳ thông tin màu nào (tức là, phạm vi Value sẽ bị bỏ hoang [0, 255]). Hy vọng rằng sẽ giúp! – mevatron

+0

Ah ok, vì vậy nó sẽ làm việc tốt hơn trong RGB?bl, gl và rl là các giá trị xanh lam, xanh lục và đỏ. Tôi có đúng không? – dom

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