本文代码实现了简单的数字水印功能,即将一个掩模图像(二值图像)的信息隐藏在一个灰度图像的最低有效位上。
//====================================================================        
// 作者   : quarryman        
// 邮箱   : quarrying{at}qq.com        
// 主页   : http://blog.csdn.net/quarryman        
// 日期   : 2013年12月23日        
// 描述   : 简单数字水印      
//====================================================================  
#include <cv.h>
#include <highgui.h>

void kcvWatermarking(IplImage* img,IplImage* mask)
{
int w=img->width;
int h=img->height;
// 确保mask中只有黑白两种灰度值
cvThreshold(mask,mask,128,255,CV_THRESH_BINARY);
for(int i=0;i<h;++i)
{
for(int j=0;j<w;++j)
{
if(CV_IMAGE_ELEM(mask,uchar,i,j))
{
CV_IMAGE_ELEM(img,uchar,i,j)|=0x1;
}
else
{
CV_IMAGE_ELEM(img,uchar,i,j)&=0xfe;
}
}
}
}

void kcvGetWatermarking(IplImage* img,IplImage* dst)
{
int w=img->width;
int h=img->height;
for(int i=0;i<h;++i)
{
for(int j=0;j<w;++j)
{
if(CV_IMAGE_ELEM(img,uchar,i,j)&0x1)
{
CV_IMAGE_ELEM(dst,uchar,i,j)=0;
}
else
{
CV_IMAGE_ELEM(dst,uchar,i,j)=255;
}
}
}
}

int main( int argc, char** argv )
{
IplImage* img=cvLoadImage("lena.jpg",0);
IplImage* mask=cvCreateImage(cvGetSize(img),8,1);
IplImage* dst=cvCreateImage(cvGetSize(img),8,1);
cvSetZero(mask);
CvFont font=cvFont(2);
char text[]="minmin, i love you!";
cvPutText(mask,text,cvPoint(50,50),&font,CV_RGB(255,255,255));
cvNamedWindow("img");
cvNamedWindow("min");
cvShowImage("img",img);
cvShowImage("min",mask);
// 执行水印
kcvWatermarking(img,mask);
cvNamedWindow("comp");
cvShowImage("comp",img);
// 获得水印
kcvGetWatermarking(img,dst);
cvNamedWindow("watermarking");
cvShowImage("watermarking",dst);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
cvReleaseImage(&mask);
cvReleaseImage(&dst);
return 0;
}

参考

https://blog.csdn.net/quarryman/article/details/17499649