2011-12-26 117 views
6

Tôi hiện đang cố di chuyển một chút mã di sản từ iPhone sang Android. Mã này sử dụng thư viện OpenCV để thực hiện một số xử lý hình ảnh. Nói chung nó đi tốt, nhưng tôi bị mắc kẹt trên một dòng mã Tôi không có ý tưởng làm thế nào có thể được chuyển đổi thành mã Java:Chuyển đổi mã OpenCV từ C++ sang Java

Scalar dMean; 
Scalar scalar; 
std::vector<Mat> channels; 
split(mat, channels); 
for(int i=0; i<3; ++i) { 
    channels[i] += dMean[i]; 
} 

Câu hỏi là - những gì nên được sử dụng thay cho toán tử + = trong Java mã để thêm một đối tượng vô hướng vào một Mat?

+0

Bạn có thể chỉ cho chúng tôi những gì bạn đã có, nơi chính xác (trong Java) bạn đang mắc kẹt? – MByD

+0

+ = là toán tử chấp nhận được đối với nguyên thủy, nhưng không cho đối tượng. Có thể bạn sẽ phải viết một phương thức có bổ sung cho đối tượng. – Kylar

+0

Mã C++ thêm đối tượng Scalar vào đối tượng Mat. Trong Java, tôi đã tạo ra cả hai đối tượng Scalar và Mat nhưng không thể tìm thấy một phương thức để thêm Scalar vào Mat.Lớp Core trong JavaCV chứa một metod tĩnh thêm (Mat, Mat, Mat), nhưng nó chỉ cho phép bạn thêm hai Mat's – Anton

Trả lời

5

Lưu ý: lấy câu trả lời này với một hạt muối, tôi đã không kiểm tra đầy đủ này;)

OPTION1:

Cách trực tiếp nhất, và nếu bạn chỉ đi xử lý một vài pixel, bằng cách sử dụng your_mat.put (hàng, col, dữ liệu)your_mat.get (hàng, col).

Vì phương pháp put() không chấp nhận các đối tượng làm thông số dữ liệu Scalar, bạn phải chuyển đổi Scalar thành nội dung mà put() chấp nhận.

Vì vậy, nếu Scalar của bạn là (1,2,3) có thể là một mảng int int [] scalar = {1,2,3}; nên thực hiện thủ thuật.

int[] scalar = ... // convert from Scalar object 

// assuming the result of get() is an int[], sum both arrays: 
int[] data = your_mat.get(row, col) + scalar // <- pseudo-code alert :D 

your_mat.put(row, col, data); 

OPTION2:

Nhưng cách khuyến cáo, đối với rất nhiều chế biến pixel, là lần đầu tiên chuyển đổi một Mat đến một Java nguyên thủy, quá trình này nguyên thủy và sau đó chuyển đổi nó trở lại Mat. Điều này là để tránh quá nhiều cuộc gọi JNI, phương pháp này thực hiện 2 cuộc gọi JNI trong khi trước đây thực hiện một lần cho mỗi lần đặt/nhận.

Các ứng dụng Java nguyên thủy loại mảng phụ thuộc vào loại Mat:

CV_8U and CV_8S -> byte[]; 
CV_16U and CV_16S -> short[]; 
CV_32S -> int[]; 
CV_32F -> float[]; 
CV_64F-> double[]; 

Vì vậy, các mã sẽ được một cái gì đó như thế này:

// assuming Mat it's of CV_32S type 
int buff[] = new int[your_mat.total() * your_mat.channels()]; 

your_mat.get(0, 0, buff); 

// buff is now Mat converted to int[] 

your_mat.put(0, 0, buff); // after processing buff, convert it back to Mat type 

OPTION 3:

Ok vậy những giải pháp này khá xấu xí, cái này không hiệu quả nhất nhưng nó ít xấu xí hơn, theo cách Java:

List<Integer> scalarList = ... // your conversion from a Scalar to a List 
List<Integer> channelsList = new ArrayList<Integer>(); 

Converters.Mat_to_vector_int(channels, channelsList); // this is an existing OpenCV4Android converter 

// process channelsList and scalarList, store in channelsList 

channels = Converters.vector_int_to_Mat(channelsList); // after processing, convert it back to Mat type 

Bây giờ tôi nghĩ về nó tùy chọn 3 khá giống với phương án 2, nếu OpenCV Converters công việc tương tự trong nội bộ như phương án 2 chuyển đổi.

+0

Mặc dù câu trả lời này không liên quan nữa, tôi sẽ chấp nhận nó vì nó có vẻ chính xác và đầy đủ – Anton

+1

Có tôi nhận thấy sau đó câu hỏi đã được một chút cũ. Nhưng vấn đề vẫn còn khá phổ biến hiện nay đối với người dùng opencv mới. AFAIK các tùy chọn này hiện là lựa chọn tốt nhất để lặp qua pixel trong java. –

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