Ask Your Question

Watermarking algorithms in OpenCV?

asked 2016-03-15 02:32:14 -0500

Arijit Datta gravatar image

Arent there watermarking algorithms in OpenCV library? I am basically searching for robust invisible and blind watermarking algorithms for mobile commerce applications. The watermark is not a logo, its a binary data which con be mapped to a URL.

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2016-03-17 15:01:32 -0500

theodore gravatar image

@Arijit Datta I think that what you are trying to achieve is called steganography. In this approach you are just discarding the bits of a pixel that they do not contain that much information and you are replacing them with the information that you want to hide/mark. It can be applied both straight to spatial domain (actual image pixels) or in the frequency domain (using dft for example). It a nice subject and area to play with. Some time ago I made the following example which you can use, it is only in the spatial domain but you can play/search a bit more and port it to the frequency domain. In the following example I am just hiding an image within another image but you can hide text or whatever you want and then recover it again applying the inverse operation. This is the example:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

// functions applies steganography in spatial domain
void steganograph(Mat &aFrontImage, Mat &aHiddenImage)
    // check if two images are the same type and size
    CV_Assert(aFrontImage.type() == aHiddenImage.type() && aFrontImage.size() == aHiddenImage.size());

    // create our stego image, where we are gonna store the final result
    Mat aStegedImage(aFrontImage.rows, aFrontImage.cols, aFrontImage.type());
    // create some temp images that we are gonna need later for the process
    Mat tFront_image, tHidden_image;

    if(aFrontImage.channels() == 3) // check if we are dealing with color images
        // populate mask matrices with the value 0xF0 or 11110000 in binary
        Mat front_mask(aFrontImage.rows, aFrontImage.cols, aFrontImage.type(), Scalar(0xF0, 0xF0, 0xF0));
        Mat hidden_mask(aHiddenImage.rows, aHiddenImage.cols, aHiddenImage.type(), Scalar(0xF0, 0xF0, 0xF0));

        // perform bitwise ANDing of two matrices and store the result in a third matrix.
        // What we achieved with this operation? Well, now the resulting tFront_image and
        // tHidden_image matrices contains only the first four important bits of each pixel
        // in aFrontImage. The remaining four bits are zero padded
        bitwise_and(aFrontImage, front_mask, tFront_image);
        bitwise_and(aHiddenImage, hidden_mask, tHidden_image);

        for(int j = 0; j < aHiddenImage.rows; j++)
            for(int i = 0; i < aHiddenImage.cols; i++)
                // right-shift the pixel components of the tHidden_image matrix by 4 bits,
                // and hence the first four bits are zero padded.
      <Vec3b>(j,i)[0] =<Vec3b>(j,i)[0] >> 4;
      <Vec3b>(j,i)[1] =<Vec3b>(j,i)[1] >> 4;
      <Vec3b>(j,i)[2] =<Vec3b>(j,i)[2] >> 4;
    }else if(aFrontImage.channels() == 1){ // check if we are dealing with grayscale images
        Mat front_mask(aFrontImage.rows, aFrontImage.cols, aFrontImage.type(), Scalar(0xF0));
        Mat hidden_mask(aHiddenImage.rows, aHiddenImage.cols, aHiddenImage.type(), Scalar(0xF0));

        bitwise_and(aFrontImage, front_mask, tFront_image);
        bitwise_and(aHiddenImage, hidden_mask, tHidden_image);

        for(int j = 0; j < aHiddenImage.rows; j++)
            for(int i = 0; i < aHiddenImage.cols; i++)
      <uchar>(j,i) =<uchar>(j,i) >> 4;

    // Finally, perform the bitwise addition of the tFront_image and tHidden_image matrices
    // to obtain aStegedImage, which is our steganograph image
    bitwise_or(tFront_image, tHidden_image, aStegedImage);

    // save and show the stego image ...
edit flag offensive delete link more

answered 2016-03-15 03:12:11 -0500

Depending on what you want to do (visible watermark? invisible watermark? prevent from copy? etc.) there is a lot to do with OpenCV (launch a simple: OpenCV watermark on google...)

This tutorial on blending 2 images could help. This StackOverflow answer also (by the way, this is the first results returned by Google). This answer (on this site!) could also help you.

For the second part of your question, I think what you want to add is a QR code. Have a look at this website, which generates a JPEG QR code that you can easily import in OpenCV.

edit flag offensive delete link more


Well, i am basically developing a desktop app which can embed an invisible watermark (watermark is digital data further modulated by a PN sequence) into an image. The output image is then printed. When a mobile app takes a snapshot of the watermarked image, the decoder should be able to extract the watermark data. This data has a mapping to a URL in a server. The decoder should be fast enough to open the URl for the user as soon as the snapshot is taken. Basically, the point is to embed an invisible URL in the image. Since, URLs can be long, instead of embedding an invisible URL, i thought of embedding digital data and keeping the URL mapping in a server. Any other idea is welcome!

Arijit Datta gravatar imageArijit Datta ( 2016-03-15 07:09:09 -0500 )edit

The decoder should also be tolerant to scale, translation, rotation, illumination variation because user may not place the mobile phone camera perfectly vertical on the watermarked image. These schemes which you have linked are spatial domain schemes. I would prefer using frequency domain since algos should be highly robust and invisible. Its not a QR code since it is invisible. When I search the term "watermark" in opencv docs, i dont get anything. Can OpenCV library be of help? Thanks!!

Arijit Datta gravatar imageArijit Datta ( 2016-03-15 07:09:34 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2016-03-15 02:32:14 -0500

Seen: 2,086 times

Last updated: Mar 17 '16