finding some time and motivated from an example at the Instant Opencv Starter book here is an example applying steganography in spatial domain by modifying the LSB values of the pixels.
// function 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
imwrite("stegedImg.png", aStegedImage);
imshow("aStegedImg", aStegedImage);
}
// function to desteganograph an image
void deSteganograph(Mat &aStegedImage)
{
// create matrices to store the results
Mat aFrontImage(aStegedImage.rows, aStegedImage.cols, aStegedImage.type());
Mat aHiddenImage(aStegedImage.rows, aStegedImage.cols, aStegedImage.type());
// Mat tFront_image, tHidden_image;
if(aFrontImage.channels() == 3) // check if we are dealing with color images
{
// populate again the mask matrices with the values 0xF0 or 11110000 in binary
// and 0x0F or 00001111 in binary depending which image we want to retrieve
Mat front_mask(aStegedImage.rows, aStegedImage.cols, aStegedImage.type(), Scalar(0xF0, 0xF0, 0xF0));
Mat hidden_mask(aStegedImage.rows, aStegedImage.cols, aStegedImage.type(), Scalar(0x0F, 0x0F, 0x0F));
// apply again bitwise_ANDing to retrieve the images
bitwise_and(aStegedImage, front_mask, aFrontImage);
bitwise_and(aStegedImage, hidden_mask, aHiddenImage);
for(int j = 0; j < aHiddenImage.rows; j++)
for(int ...
(more)
I think what you are looking for is steganography. If you search in the web you can find solutions regarding steganography and opencv library. From a quick research you will need to modify the LSB of a pixel values in order to embed the secret information. You can either do it in the initial spatial (aka. RGB) domain, or in another domain (e.g. DCT). However, have in mind that both techniques are lossy approaches.
Thanks for the response! but Steganography will modify original pixels , I need to save additional information which should't change original pixel values. I'm afraid that i can't explain the whole purpose of my project in one comment. I need the original values of pixels in future to compare the suspicious image and my original watermarked image. Hence i need a way to store a list of elements into my image in a non-removable way.
I do not think that this is possible. For example from what you are describing you need to add an extra channel to your image, where you are gonna store the additional info/data. However, I cannot see how this will not affect the output of your original RGB image. However, if someone knows a way I would interested to hear about it.
As far i have searched there is no possible way to do :( But i require a way to save the embedded places of my cover image in some sort of place into the same image.hence i can extract it and prove ownership.Would be appreciable if you can suggest any other way to do so.
then as I said steganography is the way to go. Searching a bit I found this paper which proposes a lossless method compared to other techniques. Have a look at it, it is also quite recent. Otherwise from the traditional existing methods, embedding the extra data in the dct domain seems to be less lossy compared to the spatial domain.