Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用get()和put()访问OpenCV for Java中的像素值_Java_Android_Opencv_Image Processing_Computer Vision - Fatal编程技术网

使用get()和put()访问OpenCV for Java中的像素值

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

我是使用OpenCV for JAVA的初学者。我想访问图像矩阵的各个像素值。由于OpenGV的java jar不能提供像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);
    }
mata=Highgui.imread(图像地址)\\“image_addr”是图像的地址
Mat C=A.clone();
尺寸A=A.尺寸();
对于(int i=0;i
案例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);
mata=Highgui.imread(图像地址)\\“image_addr”是图像的地址
Mat C=A.clone();
int size=(int)(A.总计()*A.通道());
字节[]临时=新字节[大小];
A.get(0,0,temp);
对于(int i=0;i
现在根据我的理解,他们应该做同样的事情。它们都访问单个像素值(全部3个通道)并将其减半。运行后我没有收到任何错误。但是,我得到的输出图像在这两种情况下是不同的。有人能解释一下问题是什么吗?可能是我不太明白get()函数是如何工作的?是因为字节()转换吗?请帮忙


谢谢

这是由于字节()强制转换造成的。在第二种情况下,我将mat image的数据类型更改为*CV_64FC3*,这样我就可以使用double[]而不是byte[],解决了这个问题

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);
mata=Highgui.imread(图像地址)//“image_addr”是图像的地址
Mat C=A.clone();
A.convertTo(A,CvType.CV_64FC3);//新增一行。
int size=(int)(A.总计()*A.通道());
双精度[]温度=新的双精度[尺寸];//使用double[]而不是byte[]
A.get(0,0,temp);
对于(int i=0;i

仅供参考,我还做了一些时间测量,使用第二种方法比第一种方法快得多。

经过大量搜索,找到了一个简单有效的解决方案-

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
Mat img=Highgui.imread(“Input.jpg”)//从文件系统读取图像并放入矩阵
int rows=img.rows()//计算行数
int cols=img.cols()//计算列数
int ch=img.channels()//计算通道数(灰度:1、RGB:3等)

对于(int i=0;这是个好问题,你能解释一下你为什么使用:(A.total()*A.channels());?total(方法返回withd*高度,为什么你乘以通道数,我知道RGB图像有3个通道…但我需要更多的澄清please@rmaik每个通道都有自己的强度值(红色、蓝色或绿色)对于每个像素。因此,图像中这些强度值的总数等于像素数*通道总数。因此,在本例中,total()给出图像和通道中的像素总数()提供通道数。它可以工作,但速度非常慢。在一台好的计算机上,8MP图像可能需要30秒。相反,您希望使用Mat.get(0,0,字节[totalNumberOfPixel*bytesPerPixel])一次读取缓冲区中的所有数据