繁体   English   中英

将OpenCV矩阵循环转换为JavaCV

[英]Converting OpenCV matrix looping to JavaCV

不久前收到了O'Reilly的书“ Learning 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; 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 );
}

这是此代码的随附说明:

在将指针计算到矩阵中时,请记住矩阵元素数据是一个并集。 因此,在取消引用此指针时,必须指示并集的正确元素才能获得正确的指针类型。 因此,要取消设置该指针,必须使用矩阵的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;
}   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM