Intereting Posts
Номер прогона Android ProGuard Android – AssertionFailedError для метода startActivity в тестовом классе ActivityUnitTestCase Android alphabetindexer с числами На какую ошибку это указывает – «new_window_surface возвращает 0x3000» Не удается заставить ScrollView прокручиваться, когда отображается мягкая клавиатура AdbCommandRejectedException Получение свойств при тестировании на эмуляторе Профилирование приложений Android с плагином Eclipse TPTP вместо отслеживания Android: OutofMemoryError: размер растрового изображения превышает бюджет VM без причины, я могу видеть Найти использование id, не работающего в Android Studio на Windows Gradle + Retrolambda: Неустранимая ошибка: невозможно найти пакет java.lang в пути к классам или bootclasspath Как удалить тему из Firebase Console? (ТСМ) Как заставить WRAP_CONTENT работать с RecyclerView Android – Раздвижное меню с подменю Выбираемый селектор не работает в Jelly Bean Android NestedScrollView имеет неправильный размер после приложения: layout_behavior

Использование get () и put () для доступа к значениям пикселей в OpenCV для Java

Я начинаю использовать OpenCV для JAVA. Я хочу получить доступ к отдельным значениям пикселей матрицы изображений. Поскольку JAVA jar для OpenCV не предлагает приятных функций, таких как C ++, я столкнулся с некоторыми проблемами. После многих поисков я обнаружил два разных способа сделать это, хотя они не объясняются должным образом (даже в документации). Мы можем сделать это либо с помощью функций get () и put (), либо путем преобразования данных mat в примитивный тип java, например массивы. Я попробовал оба, но получаю разные выходные результаты! Пожалуйста, помогите объяснить, что я делаю неправильно. Я использую их неправильно или какую-то другую глупую проблему. Я все еще новичок, поэтому, пожалуйста, простите, если это глупый вопрос. 🙂

СЛУЧАЙ 1: Использование функции get ()

Mat A = Highgui.imread(image_addr); \\"image_addr" is the address of the image Mat C = A.clone(); Size sizeA = A.size(); for (int i = 0; i < sizeA.height; i++) for (int j = 0; j < sizeA.width; j++) { double[] data = A.get(i, j); data[0] = data[0] / 2; data[1] = data[1] / 2; data[2] = data[2] / 2; C.put(i, j, data); } 

CASE 2: Использование массива

 Mat A = Highgui.imread(image_addr); \\"image_addr" is the address of the image Mat C = A.clone(); int size = (int) (A.total() * A.channels()); byte[] temp = new byte[size]; A.get(0, 0, temp); for (int i = 0; i < size; i++) temp[i] = (byte) (temp[i] / 2); C.put(0, 0, temp); 

Теперь, согласно моему пониманию, они оба должны сделать то же самое. Они оба получают доступ к отдельным значениям пикселей (все 3 канала) и составляют половину. После запуска я не получаю ошибки. Но выходное изображение, которое я получаю, отличается в этих двух случаях. Может кто-нибудь объяснить, в чем проблема? Может быть, я не понимаю, как работает функция get ()? Это из-за литья байта ()? Пожалуйста помоги.

Благодаря!

Solutions Collecting From Web of "Использование get () и put () для доступа к значениям пикселей в OpenCV для Java"

Это происходило из-за байта () кастинга. Я изменил тип данных матового изображения во втором случае на * CV_64FC3 *, так что я могу использовать double [] вместо байта [], и он решил проблему.

 Mat A = Highgui.imread(image_addr); //"image_addr" is the address of the image Mat C = A.clone(); A.convertTo(A, CvType.CV_64FC3); // New line added. int size = (int) (A.total() * A.channels()); double[] temp = new double[size]; // use double[] instead of byte[] A.get(0, 0, temp); for (int i = 0; i < size; i++) temp[i] = (temp[i] / 2); // no more casting required. C.put(0, 0, temp); 

FYI, я также сделал некоторое измерение времени, и использование второго метода намного быстрее, чем первый метод.

Нашел простое и рабочее решение после многого поиска –

 Mat img = Highgui.imread("Input.jpg"); //Reads image from the file system and puts into matrix int rows = img.rows(); //Calculates number of rows int cols = img.cols(); //Calculates number of columns int ch = img.channels(); //Calculates number of channels (Grayscale: 1, RGB: 3, etc.) for (int i=0; i<rows; i++) { for (int j=0; j<cols; j++) { double[] data = img.get(i, j); //Stores element in an array for (int k = 0; k < ch; k++) //Runs for the available number of channels { data[k] = data[k] * 2; //Pixel modification done here } img.put(i, j, data); //Puts element back into matrix } } Highgui.imwrite("Output.jpg", img); //Writes image back to the file system using values of the modified matrix 

Примечание. Важным моментом, который не упоминается нигде в Интернете, является то, что метод put не записывает пиксели на Input.jpg . Он просто обновляет значения матрицы img . Поэтому приведенный выше код ничего не меняет во входном изображении. Для получения видимого результата матрица img должна быть записана в файл, т.е. Output.jpg в этом случае. Кроме того, использование img.get(i, j) , по-видимому, является лучшим способом обработки матричных элементов, а не использованием принятого решения выше, поскольку это помогает лучше визуализировать и работать с матрицей изображений и не требует больших Смежное распределение памяти.