不久前得到了O'Reilly的“学习OpenCV”这本书,从那以后我一直在忙着将我看到的所有示例代码从OpenCV转换为JavaCV,通常也会进行一些我自己的修改。我一直试图尽可能地保持纯OpenCV(C语言)代码并避免使用Java。例如,我直接通过JavaCV中的OpenCV highgui包实现了所有的接口元素,而不是通过Java Swing。通过这样做,我希望以相对较短的顺序学习OpenCV库和一些C,以及建立一个有用的函数库,如果我决定稍后切换到纯OpenCV,我将能够轻松地转换为C. p>
无论如何,我对C知之甚少,有时在处理指针时遇到麻烦。本书推荐使用以下代码作为迭代3通道矩阵的最佳方法:
float sum( const CvMat* mat ) {
float s = 0.0f;
for(int row=0; row<mat->rows; row++ ) {
const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
for( col=0; col<mat->cols; col++ ) {
s += *ptr++;
}
}
return( s );
}
以下是此代码的附带说明:
当计算指针进入矩阵时,请记住矩阵元素数据 是一个工会。因此,在取消引用此指针时,必须指出正确的指针 union的元素,以获取正确的指针类型。然后,关闭设置 指针,必须使用矩阵的step元素。如前所述,该步骤 element以字节为单位。为安全起见,最好以字节为单位进行指针运算,并且>然后转换为适当的类型,在这种情况下浮动。尽管CVMat结构具有>为了与旧的IplImage结构兼容,高度和宽度的概念,我们&gt;使用更新的行和列来代替。最后,请注意我们为&gt;重新计算ptr;每一行而不是简单地从开头开始然后递增该指针 每次阅读。这可能看起来过分,但因为CvMat数据指针可能只是 指向较大阵列内的ROI,不能保证数据将>跨行连续。
但是我无法将其转换为JavaCV。 ptr字段(指针)似乎是一个浮点数,这让我很困惑。我认为它实际上不是一个“指针”,而是一个值,每个像素的值被添加到其中?或者它实际上是一个指针,s值找到给定行中所有列的总和?
无论如何,如果有人为我发布一些JavaCV代码以获得公平的循环,我将非常感激。我知道还有其他方法可以访问CvMat中的每个像素,但是AFAIK它们效率低或不准确。
答案 0 :(得分:6)
您提供的特定示例将最佳地转换为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;
}
答案 1 :(得分:0)
这是我最终通过试用和变通的变种。错误;迭代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;
}