2013-05-07 27 views
6

Tôi cũng quen với định dạng hình ảnh IPL được sử dụng trong OpenCV 1.1. Tuy nhiên tôi đang sử dụng phiên bản 2.4 mới nhất và muốn chuyển sang giao diện C++ của OpenCV. Đây là phương pháp mà tôi truy cập các pixel trong một hình ảnh:Từ IPLImage to Mat

int step = img->widthStep; 
int height = img->height; 
int width = img->width; 
unsigned char* data = (unsigned char*) img->imageData; 

for (int i=0; i<height; i++) 
{ 
    for (int j=0; j<step; j+=3)   // 3 is the number of channels. 
    { 
     if (data[i*step + j] > 200)  // For blue 
      data[i*step + j] = 255; 

     if (data[i*step + j + 1] > 200) // For green 
      data[i*step + j + 1] = 255; 

     if (data[i*step + j + 2] > 200) // For red 
      data[i*step + j + 2] = 255; 
    } 
} 

Tôi cần trợ giúp để chuyển đổi khối mã chính xác này với cấu trúc Mat. Tôi tìm thấy một số chức năng ở đây và ở đó nhưng nó sẽ rất hữu ích nếu tôi nhận được sự chuyển đổi chính xác của một vài dòng trên như một toàn thể.

Trả lời

8
// Mat mat; // a bgr, CV_8UC3 mat 

for (int i=0; i<mat.rows; i++) 
{ 
    // get a new pointer per row. this replaces fumbling with widthstep, etc. 
    // also a pointer to a Vec3b pixel, so no need for channel offset, either 
    Vec3b *pix = mat.ptr<Vec3b>(i); 
    for (int j=0; j<mat.cols; j++) 
    { 
     Vec3b & p = pix[j]; 
     if (p[0] > 200) p[0] = 255; 
     if (p[1] > 200) p[1] = 255; 
     if (p[2] > 200) p[2] = 255; 
    } 
} 
3

Trước tiên, bạn có thể thực hiện thao tác tương tự trên IPLImage và sử dụng hàm tạo dựng sẵn của Mat để chuyển đổi.

Thứ hai, mã của bạn có vẻ quá phức tạp, vì bạn đang thực hiện cùng một thao tác cho cả 3 thứ nguyên. Sau đây là ngăn nắp (trong ký hiệu Mat):

unsigned char* data = (unsigned char*) img.data; 

for (int i = 0; i < image.cols * image.rows * image.channels(); ++i) { 
    if (*data > 200) *data = 255; 
    ++data; 
} 

Nếu bạn muốn thres cho các kênh là khác nhau, sau đó:

unsigned char* data = (unsigned char*) img.data; 
assert(image.channels() == 3); 

for (int i = 0; i < image.cols * image.rows; ++i) { 
    if (*data > 200) *data = 255; 
    ++data; 
    if (*data > 201) *data = 255; 
    ++data; 
    if (*data > 202) *data = 255; 
    ++data; 
} 
+0

Làm tất cả mọi thứ trong IPL-hình ảnh và sau đó chuyển đổi trở lại - sẽ này đủ nhanh? tôi không muốn quá trình này mất thêm thời gian xử lý. Và vì điều phức tạp hơn - đây chỉ là một mã mẫu, giả sử tôi cần đưa ra các ngưỡng khác nhau cho màu xanh lục và xanh lam. Phương pháp của bạn sẽ hoạt động sau đó? – Soumyajit

+1

Khi bạn chuyển đổi giữa Mat và IplImage, bạn có tùy chọn để sao chép dữ liệu hay không. Nếu bạn không sao chép, chi phí thực sự rất nhỏ. Ngay cả khi bạn sao chép, tôi nghi ngờ chi phí là đáng kể cho toàn bộ quá trình xử lý của bạn mất nhiều hơn 1 giây hoặc lâu hơn. Đã thêm trường hợp cho các ngưỡng khác nhau. – guinny

+0

Mã của bạn không hoạt động nếu ma trận có một bước. Đó là trường hợp, ví dụ: cho các tiêu đề ma trận được tạo dưới dạng ROI của một ma trận khác. Sử dụng trình vòng lặp hoặc truy cập con trỏ hàng để tránh các lỗi như vậy! – ypnos