如何在OpenCV中使用Matlab的512元素查找表数组?

How to use Matlab's 512 element lookup table array in OpenCV?

本文关键字:元素 查找 数组 Matlab OpenCV      更新时间:2023-10-16

我正在OpenCV中设计形态学运算。我试图在Matlab的bwmorph中模拟函数removebridge。为此,我参考了bwmorph.m的函数定义,在那里我获得了remove和bridge的查找表数组。

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

      lut(img,lutarray,img)

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

在做了一些研究之后,我发现了这篇帖子。

当这个人说他们把图像从0-512"分割"成两部分时,他们的意思是什么?

以上方法是否正确?有没有其他选择?

bwlookup(bw,lut)

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

或者在内部,applylut都对二进制(黑白)图像执行2乘2或3乘3的邻域运算,而OpenCV的cv::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 );

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