Efficient bitwise AND on the channels of a Mat

126 Views Asked by At

I need a bitwise AND on all (3) channels of a matrix and tried this way:

Mat img(5,5,CV_8UC3);
Mat chTmp, chRes;

extractChannel(img, chTmp, 0);
extractChannel(img, chRes, 1);
bitwise_and(chTmp, chRes, chRes);
extractChannel(img, chTmp, 2);
bitwise_and(chTmp, chRes, chRes);

But extractChannel seems to allocate/ copy (?) the contents of the channels, which is costly.

Is there a better way? E.g. only access/ address the 3 channels when building chRes, without a tmp channel?

1

There are 1 best solutions below

6
fana On

Perhaps, using cv::Mat::reshape() and cv::Mat::col() will be able to avoid data copy to extract channels.

But I don't know this is efficient or not.

cv::Mat Src( 2,2, CV_8UC3 );
Src.at<cv::Vec3b>( 0,0 ) = cv::Vec3b( 0b0000'0000u, 0b0000'0001u, 0b0000'0010u );   // result should be 0000'0000 (=0)
Src.at<cv::Vec3b>( 0,1 ) = cv::Vec3b( 0b0000'1000u, 0b1000'1001u, 0b0000'1010u );   // result should be 0000'1000 (=8)
Src.at<cv::Vec3b>( 1,0 ) = cv::Vec3b( 0b1111'0000u, 0b0111'1001u, 0b0011'0000u );   // result should be 0011'0000 (=48)
Src.at<cv::Vec3b>( 1,1 ) = cv::Vec3b( 0b1111'1111u, 0b1111'1111u, 0b1111'1110u );   // result should be 1111'1110 (=254)

cv::Mat Result;
{
    cv::Mat Src_ = Src.reshape( 1, 2*2 ); //This header interprets the Src.data as {1ch, 4rows, 3cols}.
    cv::Mat Result_;
    cv::bitwise_and( Src_.col(0), Src_.col(1), Result_ );
    cv::bitwise_and( Src_.col(2), Result_, Result_ );
    Result = Result_.reshape( 1, 2 );
}

std::cout << Result << std::endl;  //(output is [0,8; 48,254])