man*_*ans 3 c++ algorithm opencv
假设我有一个mat对象,如下所示:
mat =
[75, 97, 66, 95, 15, 22;
24, 21, 71, 72, 34, 66;
21, 69, 88, 72, 64, 1;
26, 47, 26, 40, 95, 24;
70, 37, 9, 83, 16, 83];
Run Code Online (Sandbox Code Playgroud)
我想从它删除一行说第二行有这样的垫子:
[75, 97, 66, 95, 15, 22;
21, 69, 88, 72, 64, 1;
26, 47, 26, 40, 95, 24;
70, 37, 9, 83, 16, 83]
Run Code Online (Sandbox Code Playgroud)
或删除col col say col 3:
[75, 97, 95, 15, 22;
24, 21, 72, 34, 66;
21, 69, 72, 64, 1;
26, 47, 40, 95, 24;
70, 37, 83, 16, 83]
Run Code Online (Sandbox Code Playgroud)
最快的方法是什么?我可以将矩阵分解为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, 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.width, size.height - row - 1 );
cv::Rect rect2( 0, row, size.width, 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, 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, 0, size.width - col - 1, size.height );
cv::Rect rect2( col, 0, size.width - col - 1, size.height );
matIn( rect1 ).copyTo( matOut( rect2 ) );
}
Run Code Online (Sandbox Code Playgroud)使用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, matIn.data + matInOffset, 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, matIn.data + matInOffset, numBytes );
matInOffset += rowInInBytes;
matOutOffset += rowOutInBytes;
}
}
Run Code Online (Sandbox Code Playgroud)第一种方法的定时测试显示:
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
Run Code Online (Sandbox Code Playgroud)
对于第二种方法:
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
Run Code Online (Sandbox Code Playgroud)
因此,考虑到接近的时序结果和短的实现,第一种方法似乎更合适.我在github上发布了一个最小的工作示例,以验证此测试的结果.
归档时间: |
|
查看次数: |
5050 次 |
最近记录: |