- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 8UC1 Mat 图像。我正在尝试将其转换为具有 [x][y] 坐标的 Java 2D 字节数组。到目前为止,这是我所拥有的:
byte[][] arr = new byte[mat.cols()][mat.rows()];
for (int colIndex = 0; colIndex < mat.cols(); colIndex++) {
mat.get(0, colIndex, arr[colIndex]);
}
但是,这给了我完全困惑的结果。例如带有 .dump() 的垫子,如下所示:
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
给我这个(不要介意 -1,没关系):
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 0
-1 -1 -1 -1 -1 -1 -1 -1 0 0
-1 -1 -1 -1 -1 -1 -1 0 0 0
-1 -1 -1 -1 -1 -1 0 0 0 0
最佳答案
是关于Mat内部的内存布局和Mat.get的使用方式。
问题中的代码试图构建一个二维数组,其中第一个索引索引列,第二个索引索引行。
并且所述代码正在调用 Mat.get 期望在每次调用时填充一列。
内存布局。
对于单个 channel 的二维矩阵,在这种情况下,opencv 按行存储其值。并且每一行都被填充到一些适当的对齐方式。
为了便于解释,我们假设一行占用的 10 个字节被填充为总共 16 个字节。
我们的矩阵将像这样存储:
Position 0 : 255,255,255,255,255,255,255,255,255,255,?,?,?,?,?,?,
Position 16 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,?,?,?,?,?,?,
Position 32 : 255,255,255,255,255,255,255,255,255,255,?,?,?,?,?,?,
Position 48 : 255,255,255,255,255,255,255,255,255,255,?,?,?,?,?,?,
Position 64 : 255,255,255,255,255,255,255,255,255,255,?,?,?,?,?,?,
位置相对于元素在 (0,0) 的位置。从该图中应该清楚,最后一个元素,即 (4,9) 处的元素,位于位置 73。
?表示未使用的值。所以我们不能对那里的值(value)做出任何保证。
Mat 也有可能使用大小为 0 的填充,并且在我对该代码所做的测试中就是这种情况。然后布局是这样的(布局2)
Position 0 : 255,255,255,255,255,255,255,255,255,255
Position 10 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Position 20 : 255,255,255,255,255,255,255,255,255,255
Position 30 : 255,255,255,255,255,255,255,255,255,255
Position 40 : 255,255,255,255,255,255,255,255,255,255
Mat.get
这实际上是猜测,因为 documentation不完整。我必须检查来源才能确定。Mat.get(int i, int j, byte[] arr)
用存储的值填充数组 arr
,从 (i,j) 开始,直到数组已满。
那么,当我们用值为 9 的 colIndex
调用 mat.get(0, colIndex, arr[colIndex])
时会发生什么?
在上表中,(0,9) 处的元素位于位置 9。arr[colIndex]
是一个大小为 5 的数组,因此它将填充从位置 9 到13,它们是:[ 255,?,?,?,? ] 与布局 1 和 [255, 0, 0, 0, 0] 与布局 2。这就是为什么 OP 程序输出的最后一列是 [255, 0, 0, 0, 0]。请注意,在布局 2 中,当您按行顺序读取一行的最后一个元素并想要更多元素时,下一个元素将是下一行的第一个元素。arr[9]
应该包含一列,第 10 列。但是对 Mat.get 的调用不会用这样的列填充它,而是用 (0,9) 处的值和按行顺序(而不是列顺序)跟随的值填充它,由于填充(布局 1),这些值未指定或者是下一行(布局 2)中的那些。
将第一个索引保留为列,将第二个索引保留为行的丑陋解决方案:
class SimpleSample
{
static
{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void printArr( byte[][] arr )
{
for ( int y=0; y<arr[0].length; ++y )
{
for ( int x=0; x<arr.length; ++x )
System.out.print( arr[x][y] + ", " );
System.out.println("");
}
}
public static void main(String[] args)
{
Mat mat = new Mat(5, 10, CvType.CV_8UC1, new Scalar(255));
mat.row(1).setTo(new Scalar(0));
System.out.println( mat.dump() );
byte[][] arr = new byte[mat.cols()][mat.rows()];
byte[] tmp = new byte[1];
for ( int i=0; i<mat.rows(); ++i )
{
for ( int j=0; j<mat.cols(); ++j )
{
mat.get(i, j, tmp);
arr[j][i] = tmp[0];
}
}
printArr(arr);
}
}
我们得到了预期的输出:
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255;
255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
将 arr 的第一个索引更改为行,将第二个索引更改为列的解决方案。
class SimpleSample
{
static
{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void printArr( byte[][] arr )
{
for ( int y=0; y<arr.length; ++y )
{
for ( int x=0; x<arr[y].length; ++x )
System.out.print( arr[y][x] + ", " ); // Was arr[x][y] in prev code.
System.out.println("");
}
}
public static void main(String[] args)
{
Mat mat = new Mat(5, 10, CvType.CV_8UC1, new Scalar(255));
mat.row(1).setTo(new Scalar(0));
System.out.println( mat.dump() );
byte[][] arr = new byte[mat.rows()][mat.cols()];
for ( int i=0; i<mat.rows(); ++i )
mat.get(i, 0, arr[i]);
printArr(arr);
}
}
我们得到相同的输出。
请注意,虽然这里我们必须将 arr
用作 arr[y][x]
(第一行,第二列,如 opencv 中一样),但这可能不是 OP 想要的。
关于java - OpenCV 的 Java 绑定(bind) Mat.get() 给出了奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32610057/
我有这种来自 Google map 自动完成的奇怪行为(或者我可能错过了某事)...想法?奇怪的: 您在输入中输入某物,例如“伦敦” 您按 [ENTER] 你按下 [CLEAR] 按钮 你点击进入'输
这段代码与《Learning Java》(Oracle Press Books)一书中的代码完全一样,但它不起作用。我不明白为什么它不起作用,它应该起作用。我用 OpenJDK 和 Sun JDK 7
示例 1 中究竟发生了什么?这是如何解析的? # doesnt split on , [String]::Join(",",("aaaaa,aaaaa,aaaaa,aaaaa,aaaaa,aa
我需要获得方程式系统的解决方案。为此,我使用函数sgesv_()。 一切都很好,它使我感到解决方案的正确结果。 但是我得到一个奇怪的警告。 警告:从不兼容的指针类型传递'sgesv_'的参数3 我正在
我目前在制作动画时遇到一个奇怪的问题: [UIView animateWithDuration:3 delay:0
alert('works'); $(window).load(function () { alert('does not work'); });
我的代码: public class MyTest { public class StringSorter implements Comparator { public
我正在学习 JavaScript。尝试理解代码, function foo (){ var a = b = {name: 'Hai'}; document.write(a.name +''
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这按预期工作: [dgorur@ted ~]$ env -i env [dgorur@ted ~]$ 这样做: [dgorur@ted ~]$ env -i which date which: no
struct BLA { int size_; int size()const{ return size_; } } int x; BLA b[ 2 ]; BLA * p = &b[
我有以下代码: #test img {vertical-align: middle;} div#test { border: 1px solid green; height: 150px; li
我想大多数使用过 C/C++ 的人都对预处理器的工作原理有一定的直觉(或多或少)。直到今天我也是这么认为的,但事实证明我的直觉是错误的。故事是这样的: 今天我尝试了一些东西,但我无法解释结果。首先考虑
我想为 TnSettings 做 mock,是的,如果通过以下方法编写代码,它就可以工作,问题是我们需要为每个案例编写 mock 代码,如果我们只 mock 一次然后执行多个案例,那么第二个将报告异常
我的项目中有以下两个结构 typedef volatile struct { unsigned char rx_buf[MAX_UART_BUF]; //Input buffer over U
Regex rx = new Regex(@"[+-]"); string[] substrings = rx.Split(expression); expression = "-9a3dcb
我的两个应用程序遇到了一个奇怪的问题。这是设置: 两个 tomcat/java 应用程序,在同一个网络中运行,连接到相同的 MS-SQL-Server。一个应用程序,恰好按顺序位于 DMZ 中可从互联
我目前正在与 Android Api Lvl 8 上的 OnLongClickListener 作斗争。 拿这段代码: this.webView.setOnLongClickListener(new
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
只是遇到了奇怪的事情。我有以下代码: -(void)ImageDownloadCompleat { [self performSelectorOnMainThread:@selector(up
我是一名优秀的程序员,十分优秀!