本文介绍了在 OpenCV for Java 中使用 get() 和 put() 访问像素值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是使用 OpenCV for JAVA 的初学者.我想访问图像矩阵的单个像素值.由于 OpenCV 的 JAVA jar 没有提供像 C++ 这样的好功能,我遇到了一些麻烦.经过大量搜索,我发现了两种不同的方法来做到这一点,尽管它们没有得到正确的解释(甚至在文档中也没有).我们可以使用 get() 和 put() 函数或将 mat 数据转换为原始 java 类型(如数组)来做到这一点.我都尝试了,但得到了不同的输出结果!请帮助解释我做错了什么.我是用错了它们还是其他一些愚蠢的问题.我还是一个新手,所以如果这是一个愚蠢的问题,请原谅.:)

I am a beginner in using OpenCV for JAVA. I want to access individual pixel values of an image matrix. Since, JAVA jar for OpenCV doesn't offer nice functions like C++, I ran into some trouble. After lot of searching, I found out two different methods to do that though they are not explained properly (not even in documentation). We can do that either using get() and put() functions or by converting the mat data into a primitive java type such as arrays. I tried both but getting different output results! Please help explaining what am I doing wrong. Am I using them wrong or some other silly problem. I am still a newbie so please forgive if its a stupid question. :)

案例 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);
    }

案例 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() 函数是如何工作的?是因为 byte() 强制转换吗?请帮忙.

Now according to my understanding they both should do the same thing. They both access the individual pixel values (all 3 channels) and making it half. I am getting no error after running. But, the output image I am getting is different in these two cases. Can someone please explain what is the issue? May be I don't understand exactly how get() function works? Is it because of the byte() casting? Please help.

谢谢!

推荐答案

这是因为 byte() 强制转换而发生的.我在第二种情况下将 mat image 的数据类型更改为 *CV_64FC3* 以便我可以使用 double[] 而不是 byte[] 并解决了问题.

It was happening because of byte() casting. I changed the data type of mat image in second case to *CV_64FC3* so that I can use double[] instead of byte[] and it solved the problem.

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, I also did some time measurement and using second method is way faster than first method.

这篇关于在 OpenCV for Java 中使用 get() 和 put() 访问像素值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-27 20:27