Ask Your Question
1

Efficient, generic scan image

asked 2015-05-27 15:47:32 -0600

mariusz gravatar image

Hi,

Is there any generic OpenCV function/algorithm (like C++ std::transform) to perform pixel modification. I know that I can write i.e. below code. But is neither generic nor efficient.

cv::Mat image;
cv::Mat new_image;

for( int y = 0; y < image.rows; y++ )
   { for( int x = 0; x < image.cols; x++ )
        { for( int c = 0; c < 3; c++ )
             { new_image.at<Vec3b>(y,x)[c] =
                         saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta ); }
   }
}

I would like to use it like i.e.

cv::Mat src;
cv::Mat dst;
transform(src, dst, pixelUnaryFunctor);

cv::Mat src1;
cv::Mat src2;
cv::Mat dst;
transform(src1, src2, dst, pixelBinaryFunctor);
edit retag flag offensive close merge delete

Comments

1

then , just do it:

Mat img = ...
img = img * alpha + beta;

in other words, opencv already has overloaded operators for this. if you catch yourself writing your own your own per-pixel-loops, you're doing it the wrong way.

berak gravatar imageberak ( 2015-05-27 15:57:41 -0600 )edit

Thank you for answer. Sorry I provided probably but example. I know that we have also converTo image.convertTo(new_image, -1, alpha, beta);

But What about below code. Join two images base on alpha channel of image2.

    void join(cv::Mat& image, const cv::Mat& image2)
    {
        assert(image.rows == image2.rows);
        assert(image.cols == image2.cols);

        auto it = image.begin<cv::Vec4b>();
        auto it2 = image2.begin<cv::Vec4b>();
        const auto itEnd = image.end<cv::Vec4b>();
        for (; it != itEnd; ++it, ++it2)
        {
            double c1 = (255 - (*it2)[3]) / 255.0;
            double c2 = (*it2)[3] / 255.0;
            (*it)[0] = (*it)[0] * c1 + (*it2)[0] * c2;
            (*it)[1] = (*it)[1] * c1 + (*it2)[1] * c2;
            (*it)[2] = (*it)
(*it)[3] = 255;
    }
    }
mariusz gravatar imagemariusz ( 2015-05-27 16:13:47 -0600 )edit

As @berak said, just use overloaded operators, in this case applied to the corresponding channel.

LorenaGdL gravatar imageLorenaGdL ( 2015-05-28 02:34:51 -0600 )edit

I do not know how to use operators instead of below three lines. Could you write it for me?

double c1 = (255 - (*it2)[3]) / 255.0;
double c2 = (*it2)[3] / 255.0;
(*it)[0] = (*it)[0] * c1 + (*it2)[0] * c2;

Thank you in advance.

mariusz gravatar imagemariusz ( 2015-05-28 16:29:59 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-05-30 05:14:38 -0600

mariusz gravatar image

Below my implementation

void join(cv::Mat& image1, const cv::Mat& image2)
{
    assert(image1.rows == image2.rows);
    assert(image1.cols == image2.cols);

    std::vector<cv::Mat> channels;
    std::vector<cv::Mat> channels2;
    cv::split(image1, channels);
    cv::split(image2, channels2);

    cv::Mat c1 = (255.0 - channels2[3]) / 255.0;
    cv::Mat c2 = channels2[3] / 255.0;
    for (size_t i = 0; i < 3; i++)
    {
        channels[i] = channels[i].mul(c1) + channels2[i].mul(c2);
    }
    cv::merge(channels, image1);
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-05-27 15:47:32 -0600

Seen: 279 times

Last updated: May 30 '15