将OpenCV矩阵循环转换为JavaCV

不久前得到了O’Reilly的“学习OpenCV”一书,从那以后我一直在忙着将我看到的所有示例代码从OpenCV转换为JavaCV,通常也会进行一些我自己的修改。 我一直试图尽可能地保持纯OpenCV(C语言)代码并避免使用Java。 例如,我直接通过JavaCV中的OpenCV highgui包实现了所有的接口元素,而不是通过Java Swing。 通过这样做,我希望以相对较短的顺序学习OpenCV库和一些C,以及建立一个有用的函数库,如果我决定稍后切换到纯OpenCV,我将能够轻松地转换为C.

无论如何,我对C知之甚少,有时在处理指针时遇到麻烦。 本书推荐使用以下代码作为迭代3通道矩阵的最佳方法:

float sum( const CvMat* mat ) { float s = 0.0f; for(int row=0; rowrows; row++ ) { const float* ptr = (const float*)(mat->data.ptr + row * mat->step); for( col=0; colcols; col++ ) { s += *ptr++; } } return( s ); } 

以下是此代码的附加说明:

在将指针计算到矩阵中时,请记住矩阵元素数据是联合。 因此,在取消引用此指针时,必须指示union的正确元素才能获得正确的指针类型。 然后,要设置该指针,必须使用矩阵的step元素。 如前所述,step元素以字节为单位。 为了安全起见,最好以字节为单位进行指针运算,然后>转换为适当的类型,在本例中为float。 虽然CVMat结构具有>高度和宽度的概念,以便与旧的IplImage结构兼容,但我们>使用更新的行和列。 最后,请注意我们为每一行重新计算ptr,而不是简单地从开头开始,然后在每次读取时递增该指针。 这可能看起来过多,但由于CvMat数据指针可能只指向较大数组中的ROI,因此无法保证数据在行之间是>连续的。

但是我无法将其转换为JavaCV。 ptr字段(指针)似乎是一个浮点数,这让我很困惑。 我认为它实际上不是一个“指针”,而是一个值,每个像素的值被添加到哪个值? 或者它实际上是一个指针,s值找到给定行中所有列的总和?

无论如何,如果有人为我发布一些JavaCV代码以获得公平的循环,我将非常感激。 我知道有其他方法可以访问CvMat中的每个像素,但是AFAIK它们效率低或不准确。

您提供的特定示例将最佳地转换为Java

 float sum(CvMat mat) { final int rows = mat.rows(); final int cols = mat.cols(); final int step = mat.step()/4; FloatBuffer buf = mat.getFloatBuffer(); float s = 0.0f; for (int row = 0; row < rows; row++) { buf.position(row * step); for (int col = 0; col< cols; col++) { s += buf.get(); } } return s; } 

这是我最终通过试验和错误得到的变体; 迭代3通道矩阵并应用一个非常简单的滤波器(我相信Samuel的例子已经很好地涵盖了灰度值的总和)。

 static IplImage setSaturate_sv(IplImage imgIn) { IplImage imgOut = cvCloneImage(imgIn); ByteBuffer pointer = imgOut.getByteBuffer(); int height = imgIn.height(); int width = imgIn.width(); int widthStep = imgIn.widthStep(); int nChannels = imgIn.nChannels(); int rowIndex; for (int row = 0; row < height; row++) { rowIndex = row * widthStep; for (int col = 0; col < width; col++) { pointer.put((rowIndex + (col * nChannels) + 1), (byte)255); pointer.put((rowIndex + (col * nChannels) + 2), (byte)255); pointer.put((rowIndex + (col * nChannels) + 3), /* leave alone */); } } return imgOut; }