2011-12-26 3 views
6

В настоящее время я пытаюсь перенести немного устаревшего кода с iPhone на Android. Этот код использует библиотеку OpenCV для обработки некоторых изображений. В целом, это будет хорошо, но я застрял на одной строке кода, я понятия не имею, как могут быть преобразованы в Java код:Преобразование кода OpenCV из C++ в Java

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

Вопрос в том - что следует использовать вместо оператора + = в Java код для добавления объекта Scalar к Mat?

+0

Можете ли вы показать нам, что у вас есть, где именно (на Java) вы застряли? – MByD

+0

+ = допустимый оператор для примитивов, но не для объектов. Вероятно, вам придется написать метод, который добавляет для объекта. – Kylar

+0

Код C++ добавляет объект Scalar to Mat. В Java я создал объекты Scalar и Mat, но не могу найти способ добавления Scalar в Mat.Класс Core в JavaCV содержит статический метод add (Mat, Mat, Mat), но он только позволяет добавить два Mat's – Anton

ответ

5

Примечание: принять этот ответ с зерном соли, я не полностью протестированы это;)

ОПЦИЯ1:

Самый прямой путь, и если вы собираетесь только обрабатывать несколько пикселей, используя your_mat.put (строка, col, data) и your_mat.get (строка, col).

Поскольку метод put() не принимает Scalar объектов в качестве параметра данных, вы должны преобразовать Scalar к чему-то, что put() принимает.

Так что если ваш Scalar есть (1,2,3), возможно, массив int int [] scalar = {1,2,3}; должен сделать трюк.

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:

Но рекомендуемый способ, для многих обработки пикселов, является первым преобразовать Mat к примитивному, процесс Java примитивного, а затем преобразовать его обратно в Mat. Это делается для того, чтобы избежать слишком большого количества вызовов JNI, этот метод выполняет 2 вызова JNI, в то время как первый делает один за put/get.

Соответствующий Java примитивный тип массива зависит от типа Mat:

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

Так что код будет выглядеть примерно так:

// 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 

ВАРИАНТ 3:

ИТАК эти решения довольно уродливы, этот не самый эффективный, но он немного менее уродлив, по-разному:

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 

Теперь, когда я думаю об этом варианта 3 очень похожи на вариант 2, если OpenCV в Converters работы, схожей внутренне как варианта 2 преобразование.

+0

Хотя этот ответ больше не имеет отношения, я буду принимать его, как кажется правильным и полным – Anton

+1

Да, я заметил позже, что вопрос был немного старым. Но проблема все еще довольно распространена сегодня для новых пользователей opencv. AFAIK эти опции в настоящее время являются лучшими вариантами для итерации через пиксели в java. –

Смежные вопросы