Я записал код openCV. Я попытался внедрить изображение водяного знака размером 64X64 пикселя в изображение 512X512. мой код состоит из 5 частей:с использованием DCT для вставки водяного знака
- чтение двух изображений (водяной знак и оригинальный образ, который я хочу вставлять водяной знак в нем)
- изменить размер 2 прочтенных изображения в заданный размер (64х64 для водяных знаков изображения и 512x512. для исходного изображения)
- делить оригинальное изменение размера изображения на 8X8 блоков и преобразовать их с DCT.
- Вложение каждого пикселя водяного знака в каждый блок исходного изображения.
- применение инверсного DCT на каждом блоке.
У меня есть эта проблема, что все три imshows имеют одинаковые результаты. спасибо за вашу помощь :)
вот мой код:
int _tmain(int argc, _TCHAR* argv[])
{
int index=0;
int iindex=0;
vector<Mat> blocks(4096);
/////////////Part1:reading images
Mat originalImage;
originalImage = imread("C:\\MGC.jpg",CV_LOAD_IMAGE_GRAYSCALE);
Mat watermarkImage;
watermarkImage = imread("C:\\ivp_lg.bmp" , CV_LOAD_IMAGE_GRAYSCALE);
/// show original image
namedWindow("Original");
int x = 0; int y = 0;
moveWindow("Original", x, y);
imshow("Original", originalImage);
x += 100; y += 100;
//////Part 2:Leave originals alone, work on a copys. resize readed images
Mat dctImage = originalImage.clone();
Mat wmrk = watermarkImage.clone();
Mat tmp1(512, 512, CV_8UC1);
Mat tmp2(64, 64, CV_8UC1);
resize(dctImage, dctImage, tmp1.size());
resize(wmrk, wmrk , tmp2.size());
/////Part 3:break dctImage into 8X8 blocks and applying DCT on each block
for (int i = 0; i < 512; i += 8)
{
for (int j = 0; j < 512; j+= 8)
{
Mat block = dctImage(Rect(i, j, 8, 8));
block.convertTo(block, CV_32FC1);
dct(block,blocks[index]);
blocks[index].convertTo(blocks[index], CV_8UC1);
index++;
}
}
/// show transformed image
namedWindow("TransformedImage");
moveWindow("TransformedImage", x, y);
imshow("TransformedImage",dctImage);
x += 100; y += 100;
//////Part 4: embeding watermark. if corresponding pixel of watermark was 255 then element (5,5) in the block increase 200 otherwise do nothing
for(int idx=0 ; idx<4096 ; idx++)
{
int i=idx/64;
int j=idx%64;
float elem=(float) wmrk.at<uchar>(i,j);
if (elem>=128)
{
float tmp=(float) blocks[idx].at<uchar>(5,5);
float temp=tmp +200;
uchar ch=(uchar) temp;
blocks[idx].at<uchar>(5,5)=ch;
}
}
//////Part 5:applying iDCT on each block
for (int i = 0; i < 512; i += 8)
{
for (int j = 0; j < 512; j+= 8)
{
Mat block = dctImage(Rect(i, j, 8, 8));
block.convertTo(block, CV_32FC1);
idct(block,blocks[iindex]);
blocks[iindex].convertTo(blocks[iindex], CV_8UC1);
iindex++;
}
}
/// show watermarked image
namedWindow("WatermarkedImage");
moveWindow("WatermarkedImage", x, y);
imshow("WatermarkedImage",dctImage);
cvWaitKey(80000);
destroyAllWindows();
return 0;
}
Если вы можете работать с цифровым водяным знаком, используя другой метод DCT, я могу помочь вам через MATLAB использовать надежный метод водяных знаков, основанный на модуляции индекса квантования (QIM). Вы можете найти его, если вы заинтересованы. – Christina
@ Чхристина: Благодарю вас за ваше предложение. Я интересуюсь цифровым водяным знаком, но меня тоже интересует программирование на С ++, и именно от этого я хочу реализовать водяной знак openCV библиотека программирования на C++. –
Ja, так удачи! – Christina