簡體   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