2012-06-20 38 views
8

Sử dụng OpenCV 2.4CvMat và imread Vs IpImage và CvLoadImage

Tôi có hai tùy chọn để tải hình ảnh:

1- CvMat and Imread 

    2- IpImage and CvLoadImage  

Cái nào là tốt hơn để sử dụng không? Tôi đã thử trộn hai và kết thúc trong seg lỗi.

Trả lời

13

imread trả về một Mat, không phải CvMat. Chúng là hai giao diện khác nhau (Mat/imread cho C++ và Ipl ... và Cv .. cho giao diện C).

Giao diện C++ đẹp hơn, an toàn hơn và dễ sử dụng hơn. Nó tự động xử lý bộ nhớ cho bạn và cho phép bạn viết ít mã hơn cho cùng một tác vụ. Những kẻ OpenCV ủng hộ cho việc sử dụng của C++, trừ một số yêu cầu dự án rất cụ thể buộc bạn phải C.

Ví dụ (C++)

cv::Mat image = imread("path/to/myimage.jpg") 
if(image.empty()) 
    return; 

cv::imshow("Image", image); 

cv::Mat bw = image > 128; // threshold image 
cv::Mat crop = image(cv::Rect(0, 0, 100, 100)); // a 100px x 100px crop 
crop= 0; // set image to 0 

cv::waitKey(); 
// end code here 

Lưu ý rằng nếu không có quy định, tất cả các bài tập ma trận tham khảo cùng một dữ liệu . Trong ví dụ trên, các điểm ma trận crop tới image và đặt thành 0 sẽ đặt phần cụ thể của image thành 0.

Để tạo bản sao dữ liệu mới, hãy sử dụng Mat :: copyTo hoặc Mat :: clone();

Và C giao diện

IplImage* pImg = CvLoadImage("path/to/myimage.jpg"); 
if(pImg == NULL) 
    return; 

// ... big bloat to do the same operations with IplImage  

CvShowImage("Image", pImg); 
cvWaitKey(); 
CvReleaseImage(&pImg); // Do not forget to release memory. 
// end code here 
0

IplImage và Mat đều liên mui trần.

Tôi khuyên bạn nên sử dụng Mat và imread(), vì rất dễ lấy dữ liệu từ Mat.

Mat :: dữ liệu trả về con trỏ tới dữ liệu ma trận thực tế trong 1D và các giá trị có thể truy cập dễ dàng. http://opencv.itseez.com/modules/core/doc/old_basic_structures.html?highlight=mat#union%20data

Nếu bạn muốn thêm khái niệm Máy học trong OpenCV cho các thuật toán theo dõi khác nhau (ví dụ OpenTLD), bạn có thể dễ dàng truy nhập dữ liệu bằng Mat.data để đưa con trỏ đến ma trận thực.

Nhiều tiện ích của OpenCV (ví dụ CalcOpticalFlowPyrLK, v.v) yêu cầu Mat. Tôi sẽ đề nghị bạn sử dụng Mat. IplImage là điều cũ bây giờ.

0

này phụ thuộc vào cách thoải mái bạn với pointers.In IplImage bạn có thể truy cập dữ liệu như

data[i*widthstep+j*nchannels +k] 

nơi i, j, k là một số nguyên đó là cách tiếp cận khá dễ dàng. Trong ma trận bình thường của 3 chiều của nó không phải là dễ dàng để truy cập dữ liệu. Đối với bình thường truy cập dữ liệu ma trận là cho a [i] [j]

*(*(a + i) + j) is the value of jth element of ith row in matrix a 
0

Từ OpenCV_2 sách dạy nấu ăn:

Cấu trúc này được thừa hưởng từ thư viện IPL (có nghĩa là Image Intel Thư viện Processing) hiện được tích hợp với thư viện IPP (thư viện Intel Thư viện nguyên thủy hiệu năng tích hợp).Nếu bạn sử dụng mã và thư viện được tạo bằng giao diện C cũ, bạn có thể cần phải thao tác các cấu trúc IplImage đó. May mắn thay, có một cách thuận tiện để chuyển đổi một IplImage thành một đối tượng cv :: Mat.

IplImage * iplImage = cvLoadImage ("c: \ img.jpg"); cv :: Mat image4 (iplImage, false);

Hàm cvLoadImage là chức năng giao diện C để tải hình ảnh. Tham số thứ hai trong hàm tạo của cv :: Đối tượng Mat cho biết dữ liệu sẽ không được sao chép (đặt thành đúng nếu bạn muốn một bản sao mới, trong khi false là giá trị mặc định để nó có thể bị bỏ qua), đó là cả IplImage và image4 sẽ chia sẻ cùng một dữ liệu hình ảnh. Bạn cần phải cẩn thận ở đây để không tạo ra con trỏ đáng yêu. Vì lý do này, an toàn hơn để đóng gói con trỏ IplImage vào lớp con trỏ tham chiếu được cung cấp bởi OpenCV 2:

cv :: Ptr iplImage = cvLoadImage ("c: \ img.jpg");

Ngược lại, nếu bạn cần phải deallocate bộ nhớ được trỏ bởi cấu trúc IplImage, bạn cần phải làm điều đó một cách rõ ràng: cvReleaseImage (& iplImage); Hãy nhớ, bạn nên tránh sử dụng cấu trúc dữ liệu không dùng nữa này. Thay vào đó, hãy luôn sử dụng cv :: Mat.