【发布时间】:2020-06-02 06:09:47
【问题描述】:
我正在寻找将图像像素数据提取到整数列表(或任何数字表示)中。例如,具有 2 x 2 白色图像,结果将是 [255,255,255,255]。如果图像是代码生成而不是从磁盘读取,则 Mat.dump() 方法会准确打印图像像素值:
Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
System.out.println("OpenCV Mat: " + m);
Mat mr1 = m.row(1);
mr1.setTo(new Scalar(1));
Mat mc5 = m.col(5);
mc5.setTo(new Scalar(5));
System.out.println("OpenCV Mat data, "+m.total()+" elements:\n" +
m.dump());
打印准确=>
OpenCV Mat: Mat [ 5*10*CV_8UC1, isCont=true, isSubmat=false,
nativeObj=0x1415d50, dataAddr=0x13a6880 ]
OpenCV Mat data, 50 elements:
[ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
1, 1, 1, 1, 1, 5, 1, 1, 1, 1;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
0, 0, 0, 0, 0, 5, 0, 0, 0, 0]
但如果我在磁盘上写入 Mat "m" 内容,然后我再次读取它,dump() 方法会吐出奇怪的输出:
Imgcodecs.imwrite(TRAIN_PATH_PROC+"m.jpg",m);
m = null;
m = Imgcodecs.imread(TRAIN_PATH_PROC+"m.jpg");
System.out.println("Fresly read m, "+m.total()+" elements:\n"+m.dump());
打印
Fresly read m, 50 elements:
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
5, 5, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1;
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 5,
5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
5, 5, 5, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
由于我需要从读取的图像中提取 int 值,并依赖 dump() 来表示字符串,这给我带来了麻烦。
编辑:
我已经设法简单地使用来提取数据
List<Integer> values = new ArrayList<>();
for (int i = 0; i < m.rows(); i++) {
for (int j = 0; j < m.cols(); j++) {
values.add((int)m.get(i,j)[0]);
}
}
【问题讨论】:
-
另外,我忘了说,dump() 方法会扭曲任何磁盘读取的图像数据,而不仅仅是通过 Imgcodecs.imwrite() 编写代码的图像
-
JPEG 是一种有损文件格式。您不一定会取回您编写的相同数据。
-
@AndyTurner 可能是这样,但为什么 .total() 只返回 50 个元素?另外,重读前后图片的字节大小是一样的