2013-05-16 38 views
7

Có giải pháp nào để truy cập các pixel dọc theo đường cong/đường dẫn không? chúng ta có thể sử dụng LineIterator để làm điều đóTruy cập các pixel dọc theo đường cong/đường dẫn bằng cách sử dụng opencv

+1

thể trùng lặp của [OpenCV - Tiếp cận pixel dọc theo đường cong/path] (http://stackoverflow.com/questions/5078387/opencv-access-to-pixels-along-the-curve-path) –

+0

bạn lấy đường cong/đường dẫn từ đâu? Hoặc bạn cho phép loại đường nào? Đa thức? Splines? – Micka

Trả lời

4

Ok, đây là một cách để truy cập pixel dọc theo một đường cong được kết nối có thể được parametrized. Có thể có những cách hiệu quả hơn, nhưng cách này khá đơn giản: chỉ cần lấy mẫu đường cong trong các bước tham số để bạn không truy cập pixel hai lần và không bỏ qua pixel:

Tôi đã lấy một hàm tham số từ wikipedia như một mẫu: http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions

enter image description here

int main() 
{ 
cv::Mat blank = cv::Mat::zeros(512,512,CV_8U); 

// parametric function: 
// http://en.wikipedia.org/wiki/Parametric_equation#Some_sophisticated_functions 
// k = a/b 
// x = (a-b)*cos(t) + b*cos(t((a/b)-1)) 
// y = (a-b)*sin(t) - b*sin(t((a/b)-1)) 

float k = 0.5f; 
float a = 70.0f; 
float b = a/k; 

// translate the curve somewhere 
float centerX = 256; 
float centerY = 256; 

// you will check whether the pixel position has moved since the last active pixel, so you have to remember the last one: 
int oldpX,oldpY; 
// compute the parametric function's value for param t = 0 
oldpX = (a-b)*cos(0) + b*cos(0*((a/b)-1.0f)) + centerX -1; 
oldpY = (a-b)*sin(0) - b*sin(0*((a/b)-1.0f)) + centerY -1; 

// initial stepsize to parametrize the curve 
float stepsize = 0.01f; 

//counting variables for analyzation 
unsigned int nIterations = 0; 
unsigned int activePixel = 0; 

// iterate over whole parameter region 
for(float t = 0; t<4*3.14159265359f; t+= stepsize) 
{ 
    nIterations++; 

    // compute the pixel position for that parameter 
    int pX = (a-b)*cos(t) + b*cos(t*((a/b)-1.0f)) + centerX; 
    int pY = (a-b)*sin(t) - b*sin(t*((a/b)-1.0f)) + centerY; 

    // only access pixel if we moved to a new pixel: 
    if((pX != oldpX)||(pY != oldpY)) 
    { 
     // if distance to old pixel is too big: stepsize was too big 
     if((abs(oldpX-pX)<=1) && (abs(oldpY-pY)<=1)) 
     { 
      //--------------------------------------------------------------- 
      // here you can access the pixel, it will be accessed only once for that curve position! 
      blank.at<unsigned char>((pY),(pX)) = blank.at<unsigned char>((pY),(pX))+1; 
      //--------------------------------------------------------------- 

      // update last position 
      oldpX = pX; 
      oldpY = pY; 

      activePixel++; // count number of pixel on the contour 
     } 
     else 
     { 
      // adjust/decrease stepsize here 
      t -= stepsize; 
      stepsize /= 2.0f; 

      //TODO: choose smarter stepsize updates 
     } 
    } 
    else 
    { 
     // you could adjust/increase the stepsize here 
     stepsize += stepsize/2.0f; 

     //TODO: prevent stepsize from becoming 0.0f !! 
     //TODO: choose smarter stepsize updates 
    } 

} 
std::cout << "nIterations: " << nIterations << " for activePixel: " << activePixel << std::endl; 

cv::imwrite("accessedOnce.png", blank>0); 
cv::imwrite("accessedMulti.png", blank>1); 

cv::waitKey(-1); 
return 0; 
} 

cho những kết quả này:

điểm ảnh truy cập một lần:

enter image description here

điểm ảnh được truy cập nhiều hơn một lần:

enter image description here

ngõ ra: nIterations: 1240 for activePixel: 1065

+0

chúng ta có thể sử dụng chuột để di chuyển đường cong bằng opencv không? – AHF

+0

@AHF bạn có ý gì khi di chuyển đường cong? openCV có một số giao diện để sử dụng các đầu vào chuột. Nhưng thuật toán của tôi là để "truy cập" (có nghĩa là xử lý tự động) mỗi điểm ảnh được nhấn bởi một đường cong tham số (f (t)). – Micka

+0

như tôi nhà nước ở đây http://stackoverflow.com/questions/23641208/how-to-draw-curve-on-control-points-using-opencv tôi cần phải vẽ ba đường cong cho RGB và di chuyển đường cong của họ, mọi thứ hoạt động tốt nhưng vẽ đường cong để di chuyển với con chuột là tạo ra vấn đề cho tôi như tôi đã không nhận được nhiều ví dụ tốt trên internet – AHF

4

Tôi không nghĩ có bất kỳ chức năng built-in cho việc này. Trước tiên, bạn cần xác định đường/đường cong trong cấu trúc cv::Mat và sau đó tiếp tục từ đó. Hãy để tôi giải thích với một ví dụ.

  1. Bạn có một hình ảnh, cv::Mat input_image và bạn sử dụng một cv::HoughLinesDetector để phát hiện dòng trong hình ảnh được lưu trữ trong cv::Mat hough_lines.
  2. Sau đó bạn sẽ cần phải lặp qua hough_lines và cư cv::Mat hough_Mat(cv::Size(input_image.size())) (mà phải được chuyển đổi sang một hình ảnh BGR nếu bạn muốn hiển thị dòng của bạn rực rỡ so với dữ liệu gốc.
  3. Sau đó, bạn chỉ cần lặp qua hough_Mat mà pixel ở trên zero và sau đó chỉ cần truy cập vào cùng một vị trí trong input_image.

Mặc dù ví dụ này là một trong những đơn giản sử dụng Hough transform, bạn có thể sử dụng nó với bất kỳ đường cong khác, miễn là bạn có dữ liệu của đường cong WRT ảnh gốc.

HTH

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