OpenCV学习第十二篇:带透明通道图像合成(缩放,旋转,和ROI)

来源:互联网 发布:脸部去角质 知乎 编辑:程序博客网 时间:2024/06/07 15:55

第一步:获取素材图片

    Mat src, dst;    src = imread("F:/识图/底图.PNG", 1);    dst = imread("logo", -1);

【ps:这里需要注意的是透明度图片获取,后面的参数带-1】
第二步:缩放Logo

Mat zoomPrint( Mat src,float zoom) {    resize(src, src, Size(0, 0), zoom, zoom, INTER_LINEAR);    return src;}

第三步:旋转Logo

//旋转void rotatePrint(Mat src, float angle) {    Point center = Point(src.cols / 2, src.rows / 2);    float scale = 1;    Mat rot_mat = getRotationMatrix2D(center, angle, scale);    warpAffine(src, src, rot_mat, src.size());}

第四步:合成两张图片
方法一:

void combineBehind(Mat src,Mat dst) {    int rownumber = src.rows;    int colnumber = src.cols;    for (int i = 0; i < rownumber; i++)    {        for (int j = 0; j < colnumber; j++)        {            float alpha = src.at<Vec4b>(i, j)[3];            if (alpha <= 0) {                src.at<Vec4b>(i, j)[0] = dst.at<Vec3b>(i, j)[0];                src.at<Vec4b>(i, j)[1] = dst.at<Vec3b>(i, j)[1];                src.at<Vec4b>(i, j)[2] = dst.at<Vec3b>(i, j)[2];            }               }    }}

【把透明度区域换为另外一张图】
方法二:

//平移印花int combinePrintReproduction(Mat &dst, Mat &scr, double scale){    if (dst.channels() != 3 || scr.channels() != 4)    {        return true;    }    if (scale < 0.01)        return false;    std::vector<cv::Mat>scr_channels;    std::vector<cv::Mat>dstt_channels;    split(scr, scr_channels);    split(dst, dstt_channels);    CV_Assert(scr_channels.size() == 4 && dstt_channels.size() == 3);    if (scale < 1)    {        scr_channels[3] *= scale;        scale = 1;    }    for (int i = 0; i < 3; i++)    {        dstt_channels[i] = dstt_channels[i].mul(255.0 / scale - scr_channels[3], scale / 255.0);        dstt_channels[i] += scr_channels[i].mul(scr_channels[3], scale / 255.0);    }    merge(dstt_channels, dst);    return true;}

【注意dst参数是一个ROI区域,这个方法可以合成可以保留alpha通道,而方法addWeighted不行】

欢迎留言,有问题可以私密我!或者加群《601408323》!