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

第一步:获取素材图片

    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(i, j)[3];
            if (alpha <= 0) {
                src.at(i, j)[0] = dst.at(i, j)[0];
                src.at(i, j)[1] = dst.at(i, j)[1];
                src.at(i, j)[2] = dst.at(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::vectorscr_channels;
    std::vectordstt_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》!

你可能感兴趣的:(OpenCV学习旅程)