@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.
tHidden_image.at<Vec3b>(j,i)[0] = tHidden_image.at<Vec3b>(j,i)[0] >> 4;
tHidden_image.at<Vec3b>(j,i)[1] = tHidden_image.at<Vec3b>(j,i)[1] >> 4;
tHidden_image.at<Vec3b>(j,i)[2] = tHidden_image.at<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++)
{
tHidden_image.at<uchar>(j,i) = tHidden_image.at<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 ...
(more)