【问题标题】:How to use Matlab's 512 element lookup table array in OpenCV?如何在 OpenCV 中使用 Matlab 的 512 元素查找表数组?
【发布时间】:2016-09-10 15:29:18
【问题描述】:

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

在这一步之后,Matlab 和 OpenCV 的过程是相同的。

      lut(img,lutarray,img)

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

在做了一些研究之后,我遇到了this post

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

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

【问题讨论】:

  • 没有人吗?我认为这个人的意思是他正在对大小为 512 箱 (??) 的直方图的前半部分 (0-255) 和后半部分 (256-511) 应用这些操作,但这又是我的猜想,我可能完全偏离轨道。尝试联系那个人(sonmi),但它直接进入邮件列表@yahoogroups。谁能帮我这个?如何在 openCV 中使用 Matlab lutarray 处理二进制图像?
  • 请不要在这里破坏您自己的帖子。我们希望每个提出好问题的人都能得到答案,但由于这里 99% 的人都是志愿者,我们无法保证。
  • bwlookup(BW,lut)applylut 对二进制或灰度图像 BW 执行 2×2 或 3×3 非线性邻域滤波操作,其中 cv::LUT 是每像素查找表手术。所以是的,你可以分割图像来执行后者,但首先提到的是,bwmorph.m 中的 bw = applylut(bw, lut) 无法使用 cv::LUT 或其他常用 OpenCV 函数复制。
  • 没有。 cv::LUT 不是邻域运算,而是所有 (x,y) 的 B(x,y) bwmorphs 删除图像减去星形内核的侵蚀。桥接需要更多的努力。
  • @halfer 抱歉,如果您觉得我忽略了您。我觉得如果我回复你,你可能会认为我在和你吵架,这根本不是我的本意。但是感谢您清理帖子以及您所做的一切。

标签: c++ opencv image-processing lookup-tables image-morphology


【解决方案1】:

bwlookup(bw,lut)

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

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

//! 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 );

我颠倒了索引出现在查找表中的顺序(无论操作是否对称)。

【讨论】:

  • 您好@mainactual,非常感谢您的回复。我想问你,你是如何实现形态学操作的?我刚刚为 lutarray 尝试了这个东西,以便在二进制图像上删除,我得到的只是一个黑屏。
  • @user6334139,您可以将 lut 数组 (1 & 0) 乘以所需的输出值(通常为 0xFF),以便输出跟随。或者重新调整out。我想很难减少屏幕上的 1s。我刚刚将 MATLAB 的查找表保存在 png 中并以这种方式导入。
  • 好的,开始工作了!将用更多的形态学操作对其进行测试并让您知道。同时,你能告诉我你对代码的解释吗?里面发生了什么?
  • @user6334139,它通过根据其在邻域中的位置设置位 [0:8] 开/关来制作 3×3 邻域的模式。之后,任何这样的形态学操作都变成了 O(1) 查找。
  • 您好,我检查了实现并给出了结果。移除和桥接以及任何其他 LUTarray 操作的结果相同。我在matlab中查看了他们两个的结果,他们根本不匹配结果。我正在查看 octave 对 bwmorph.m kernel = - conndef (ndims (bw), "minimal") 的定义;内核(ceil(数字(内核)/2))= nnz(内核)-1; morph = @(x) convn (x, kernel, "same") > 0;
猜你喜欢
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2023-03-08
相关资源
最近更新 更多