private void EmbedWatermark(double[,] data) { double[,] watermarkData = new double[_watermarkPixels.Width, _watermarkPixels.Height]; for (int x = 0; x < _watermarkPixels.Width; x++) { for (int y = 0; y < _watermarkPixels.Height; y++) { watermarkData[x, y] = _watermarkPixels.R[x, y] > 125 ? 255 : 0; } } ParallelHaar.FWT(data, 2); var subband = LL2(data); Parallel.For(0, _watermarkPixels.Height, y => { for (int x = 0; x < _watermarkPixels.Width; x++) { var block = subband.Submatrix(x * BlockSize, x * BlockSize + BlockSize - 1, y * BlockSize, y * BlockSize + BlockSize - 1); CosineTransform.DCT(block); var midbandSum = Math.Max(2, Math.Abs(MidBand(block).Sum())); var sigma = (watermarkData[x, y] > 125 ? 3 : -3); block[1, 2] += midbandSum * sigma; block[2, 0] += midbandSum * sigma; block[2, 1] += midbandSum * sigma; block[2, 2] += midbandSum * sigma; CosineTransform.IDCT(block); for (int i = 0; i < BlockSize; i++) { for (int j = 0; j < BlockSize; j++) { subband[x * BlockSize + i, y * BlockSize + j] = block[i, j]; } } } }); BackApplySubBand(data, subband); ParallelHaar.IWT(data, 2); }
private WatermarkResult RetrieveWatermark(double[,] data) { var origWidth = data.GetUpperBound(0) + 1; var origHeight = data.GetUpperBound(1) + 1; if (DiffWidth - origWidth > 0 || DiffHeight - origHeight > 0) { var top = (DiffHeight - origHeight) / 2; var left = (DiffWidth - origWidth) / 2; var bottom = (DiffHeight - origHeight) - top; var right = (DiffWidth - origWidth) - left; data = data.Pad(left, top, right, bottom); } double[,] recoveredWatermarkData = new double[_watermarkPixels.Width, _watermarkPixels.Height]; ParallelHaar.FWT(data, 2); var subband = LL2(data); var width = subband.GetUpperBound(0) + 1; var height = subband.GetUpperBound(1) + 1; Parallel.For(0, _watermarkPixels.Height, y => { for (int x = 0; x < _watermarkPixels.Width; x++) { if (x * BlockSize + BlockSize > width) { return; } if (y * BlockSize + BlockSize > height) { return; } var block = subband.Submatrix(x * BlockSize, x * BlockSize + BlockSize - 1, y * BlockSize, y * BlockSize + BlockSize - 1); CosineTransform.DCT(block); recoveredWatermarkData[x, y] = (MidBand(block).Sum() > 0) ? 255 : 0; } }); double similiar = 0; double total = (width / 4) * (height / 4); for (int x = 0; x < _watermarkPixels.Width; x++) { for (int y = 0; y < _watermarkPixels.Height; y++) { var oldValue = _watermarkPixels.R[x, y] > 125 ? 255 : 0; if (recoveredWatermarkData[x, y] == oldValue) { similiar++; } } } var similarity = Math.Round((similiar / total) * 100); var recoveredData = new RgbData(recoveredWatermarkData); var recoveredWatermarkBytes = _imageHelper.SavePixels(recoveredData); return(new WatermarkResult(similarity, recoveredWatermarkBytes)); }