Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Watermarking Images: preserve quality, control opacity

I set myself a task to create a simple OpenCV program to watermark image. The program will overlay a logo on the bottom right of an image. It will place the logo there with full opacity or slightly transparent. I have some questions whether I have done things correctly and what I can improve.

  • Q1: How can I control the opacity of the logo when I call cv::addWeighted()? I have tried different beta values but they always turn out the same more or less
  • Q2: Does my code preserve the image quality? I don't think it does, for example; the image I load in is 2mb and when I watermark then save it as a JPEG it is 100kb so I've lost quality. How can I preserve quality?
  • Q3: The logo image will always be a PNG with transparent (black?) background. When I threshold to create a mask of the logo I get artifacts or an unclean extraction of the logo. How could I accurately extract the logo without artifacts or losing detail?

    Mat src = imread("./images/pan1.jpg");  
    Mat logo = imread("./images/logo.png"); 
    
    // Watermark image: overlay logo slightly faded/transparent
    Mat watermarked;
    Mat logoResized = Mat(src.rows, src.cols, CV_8UC3);
    // Make the logo image same size as the src image
    copyMakeBorder(logo, logoResized, src.rows - logo.rows, 0, src.cols - logo.cols, 0, BORDER_CONSTANT, { 0,0,0 });
    addWeighted(src, 1.0, logoResized, 1.0, 0, watermarked); // Q1
    imshow("Watermarked Opacity", watermarked);
    imwrite("./images/pan-watermarked1.jpg", watermarked);
    
    
    // Overlay logo
    Mat logoGray, thresh;
    cvtColor(logo, logoGray, CV_BGR2GRAY);
    threshold(logoGray, thresh, 1, 255, CV_THRESH_BINARY);
    Rect r(res.cols-logo.cols, res.rows-logo.rows, logo.cols, logo.rows);
    logo.copyTo(src(r), thresh);
    imshow("Watermarked", src);
    imwrite("./images/pan-watermarked2.jpg", src);