1. 程式人生 > >opencv實現png圖片疊加邊緣透明問題

opencv實現png圖片疊加邊緣透明問題

原圖:

png圖:

結果:

實現程式碼如下:

void main()
{
    cv::Mat srcImg=cv::imread("E://srcImg.jpg");
    cv::namedWindow("srcImg");
    cv::imshow("srcImg",srcImg);
    cv::waitKey(0);
    cv::Mat logo=cv::imread("E://car.png",-1);
    mergeImg(srcImg,logo,1,1,0,cv::Point(100,100));
    cv::namedWindow("dst");
    cv::imshow("dst",srcImg);
    cv::waitKey(0);
}

bool mergeImg(cv::Mat &dst,cv::Mat &src,double scale=1.0,double size=1.0,double angle=0,cv::Point location = cv::Point(0, 0))
{
    if (dst.channels() != 3 || src.channels() != 4 || location.x>dst.cols || location.y>dst.cols)
    {
        return false;
    }


    cv::Mat small_size = src.clone();

    if (size != 1 || angle != 0) {
        int width = src.cols>(dst.cols - location.x) ? (dst.cols - location.x) : src.cols;
        int length = src.rows>(dst.rows - location.y) ? (dst.rows - location.y) : src.rows;
        cv::Mat rotation = cv::getRotationMatrix2D(cv::Point2f(length / 2, width / 2), angle, size);
        cv::warpAffine(small_size, small_size, rotation, cv::Size(width, length));
    }

    cv::Mat dst_part(dst, cv::Rect(location.x, location.y, small_size.cols, small_size.rows));

    std::vector<cv::Mat>src_channels;
    std::vector<cv::Mat>dst_channels;
    cv::split(small_size, src_channels);
    cv::split(dst_part, dst_channels);
  
    if (scale < 1)
    {
        src_channels[3] *= scale;
        scale = 1;
    }
    for (int i = 0; i < 3; i++)
    {
        dst_channels[i] = dst_channels[i].mul(255.0 / scale - src_channels[3], scale / 255.0);
        dst_channels[i] += src_channels[i].mul(src_channels[3], scale / 255.0);
    }
    cv::merge(dst_channels, dst_part);
    return true;
}