2

我在 OpenCV 中设计形态学操作。我试图模仿函数removebridgeMatlab 的 bwmorph。为此,我参考了 bwmorph.m 的函数定义,在那里我获得了用于删除和桥接的查找表数组。

在该步骤之后,Matlab 和 OpenCV 的过程相同。

      lut(img,lutarray,img)

问题是 Matlab 使用 512 元素(9 位)查找表方案,而 OpenCV 使用 256 元素(8 位)查找表方案,如何在 OpenCV 中使用 Matlab lutarray?

在做了一些研究后,我发现了这篇文章

当他们说他们将图像从 0-512 “拆分”然后分成两部分时,他们是什么意思?

上述方法是否正确?有没有其他方法可以做到这一点?

4

1 回答 1

3

bwlookup(bw,lut)

http://se.mathworks.com/help/images/ref/bwlookup.html

或者在内部,applylut两者都对二进制(黑白)图像执行 2×2 或 3×3 邻域运算,而 OpenCVcv::LUT执行每像素灰度级变换(与 MATLAB 密切相关intlut)。后者的一个例子是对灰度图像执行伽马校正。

//! transforms array of numbers using a lookup table: dst(i)=lut(src(i))
CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst,
                  int interpolation=0);

据我所知,OpenCV 中没有邻域bwlookup实现。但是,按照 MATLAB 的描述bwlookup,您可以自己编写。

// performs 3-by-3 lookup on binary image
void bwlookup( 
    const cv::Mat & in, 
    cv::Mat & out, 
    const cv::Mat & lut,
    int bordertype=cv::BORDER_CONSTANT, 
    cv::Scalar px = cv::Scalar(0) ) 
{
    if ( in.type() != CV_8UC1 )
        CV_Error(CV_StsError, "er");
    if ( lut.type() != CV_8UC1 || lut.rows*lut.cols!=512 || !lut.isContinuous() )
        CV_Error(CV_StsError, "lut size != 512" );
    if ( out.type() != in.type() || out.size() != in.size() )
        out = cv::Mat( in.size(), in.type() );

    const unsigned char * _lut = lut.data;
    cv::Mat t;
    cv::copyMakeBorder( in,t,1,1,1,1,bordertype,px);
    const int rows=in.rows+1;
    const int cols=in.cols+1;
    for ( int y=1;y<rows;++y)
    {
        for ( int x=1;x<cols;++x)
        {
            int L = 0;
            const int jmax=y+1;
#if 0 // row-major order
            for ( int j=y-1, k=1; j<=jmax; ++j, k<<=3 )
            {
                const unsigned char * p = t.ptr<unsigned char>(j) + x-1;
                for ( unsigned int u=0;u<3;++u )
                {
                    if ( p[u] )
                        L += (k<<u);
#else // column-major order (MATLAB)
            for ( int j=y-1, k=1; j<=jmax; ++j, k<<=1 )
            {
                const unsigned char * p = t.ptr<unsigned char>(j) + x-1;
                for ( unsigned int u=0;u<3;++u )
                {
                    if ( p[u] )
                        L += (k<<3*u);
#endif
                }
            }
            out.at<unsigned char>(y-1,x-1)=_lut[ L ];
        }
    }
}

我对其进行了测试removebridge因此应该可以工作。希望有帮助。

编辑:检查随机查找表后,

lut = uint8( rand(512,1)>0.5 ); % @MATLAB
B = bwlookup( A, lut );

我翻转了索引出现在查找表中的顺序(操作是否对称无关紧要)。

于 2016-06-02T07:03:16.373 回答