加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 从cv mat中删除行或col的最佳方法是什么

发布时间:2020-12-16 09:57:31 所属栏目:百科 来源:网络整理
导读:假设我有一个mat对象,如下所示: mat = [75,97,66,95,15,22; 24,21,71,72,34,66; 21,69,88,64,1; 26,47,26,40,24; 70,37,9,83,16,83]; 我想从它删除一行说第二行有这样的垫子: [75,22; 21,1; 26,24; 70,83] 或删除col col say col 3: [75,22; 24,66; 21,83
假设我有一个mat对象,如下所示:

mat = 
   [75,97,66,95,15,22;
    24,21,71,72,34,66;
    21,69,88,64,1;
    26,47,26,40,24;
    70,37,9,83,16,83];

我想从它删除一行说第二行有这样的垫子:

[75,22;
 21,1;
 26,24;
 70,83]

或删除col col say col 3:

[75,22;
 24,66;
 21,83]

最快的方法是什么?我可以将矩阵分解为ROI,然后将它们相互合并,但有没有更好的方法?

解决方法

我测试了两种方法:

>使用cv :: Rect和cv :: Mat :: copyTo:

// Removing a row
cv::Mat matIn;    // Matrix of which a row will be deleted.
int row;          // Row to delete.
int col;          // Column to delete.
cv::Mat matOut;   // Result: matIn less that one row.

if ( row > 0 ) // Copy everything above that one row.
{
    cv::Rect rect( 0,size.width,row );
    matIn( rect ).copyTo( matOut( rect ) );
}

if ( row < size.height - 1 ) // Copy everything below that one row.
{
    cv::Rect rect1( 0,row + 1,size.height - row - 1 );
    cv::Rect rect2( 0,row,size.height - row - 1 );
    matIn( rect1 ).copyTo( matOut( rect2 ) );
}

// Removing a column
if ( col > 0 ) // Copy everything left of that one column.
{
    cv::Rect rect( 0,col,size.height );
    matIn( rect ).copyTo( matOut( rect ) );
}

if ( col < size.width - 1 ) // Copy everything right of that one column.
{
    cv::Rect rect1( col + 1,size.width - col - 1,size.height );
    cv::Rect rect2( col,size.height );
    matIn( rect1 ).copyTo( matOut( rect2 ) );
}

>使用std :: memcpy和cv :: Mat :: data:

// Removing a row
int rowSizeInBytes = size.width * sizeof( T );

if ( row > 0 )
{
    int numRows  = row;
    int numBytes = rowSizeInBytes * numRows;
    std::memcpy( matOut.data,matIn.data,numBytes );
}

if ( row < size.height - 1 )
{
    int matOutOffset = rowSizeInBytes * row;
    int matInOffset  = matOutOffset + rowSizeInBytes;

    int numRows  = size.height - ( row + 1 );
    int numBytes = rowSizeInBytes * numRows;
    std::memcpy( matOut.data + matOutOffset,matIn.data + matInOffset,numBytes );
}

// Removing a column
int rowInInBytes  = size.width * sizeof( T );
int rowOutInBytes = ( size.width - 1 ) * sizeof( T );

if ( col > 0 )
{
    int matInOffset = 0;
    int matOutOffset = 0;
    int numCols = col;
    int numBytes = numCols * sizeof( T );

    for ( int y = 0; y < size.height; ++y )
    {
        std::memcpy( matOut.data + matOutOffset,numBytes );

        matInOffset  += rowInInBytes;
        matOutOffset += rowOutInBytes;
    }
}

if ( col < size.width - 1 )
{
    int matInOffset = ( col + 1 ) * sizeof( T );
    int matOutOffset = col * sizeof( T );
    int numCols = size.width - ( col + 1 );
    int numBytes = numCols * sizeof( T );

    for ( int y = 0; y < size.height; ++y )
    {
        std::memcpy( matOut.data + matOutOffset,numBytes );

        matInOffset  += rowInInBytes;
        matOutOffset += rowOutInBytes;
    }
}

第一种方法的定时测试显示:

Removed:      row
Method:       cv::Rect + cv::Mat::copyTo()
Iterations:   10000
Size:         [500 x 500]
Best time:    67ms
Worst time:   526ms
Average time: 70.9061ms
Median time:  70ms

Removed:      column
Method:       cv::Rect + cv::Mat::copyTo()
Iterations:   10000
Size:         [500 x 500]
Best time:    64ms
Worst time:   284ms
Average time: 80.3893ms
Median time:  79ms

对于第二种方法:

Removed:      row
Method:       std::memcpy and/or for-loop
Iterations:   10000
Size:         [500 x 500]
Best time:    31ms
Worst time:   444ms
Average time: 68.9445ms
Median time:  68ms

Removed:      column
Method:       std::memcpy and/or for-loop
Iterations:   10000
Size:         [500 x 500]
Best time:    49ms
Worst time:   122ms
Average time: 79.3948ms
Median time:  78ms

因此,考虑到接近的时序结果和短的实现,第一种方法似乎更合适.
我发布了minimal working example on github以验证此测试的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读