精华内容
下载资源
问答
  • DCT域数字水印的资料 主要介绍多媒体数字水印技术 DCT域明文水印和盲水印饿的算法介绍 水印的嵌入和提取
  • 提出了一种在数字图像上实现的盲水印算法,嵌入的水印是 64×64×8 bit灰度图。该算法用宿主图像的8×8分块的 DCT域低频对应系数,进行量化取余的方法嵌入水印。由于引入误差很小,嵌入水印后的宿主图像质量很高,保证了...
  • 提出了一种基于粒子群优化的DCT盲水印算法。该算法采用粒子群优化在图像DCT变换域中寻找最优的水印嵌入位置,并综合考虑不可见性和鲁棒性两个数字水印基本要求,以PSNR值和NC值的线性组合为适应度函数。根据粒子群...
  • 针对提高水印算法的鲁棒性进行研究,提出一种基于zigzag扫描的DCT鲁棒数字盲水印算法。算法对分块后DCT域的中、低频系数进行zigzag扫描得到一维数列,利用每个数列数学范数比值和量化索引调制原理实现数字水印的嵌入...
  • 基于HVS的DCT域灰度图像盲水印算法,张奎,廖述剑,介绍了一种灰度图像的盲水印算法。该算法首先对水印进行Arnold置乱变换,然后采用基于混合光学双稳模型的混沌序列对图像进行加密;
  • 离散余弦变换(DCT)在彩色图像盲水印技术中的应用.pdf离散余弦变换(DCT)在彩色图像盲水印技术中的应用.pdf离散余弦变换(DCT)在彩色图像盲水印技术中的应用.pdf离散余弦变换(DCT)在彩色图像盲水印技术中的应用...
  • 为了统计不同算法的透明性和鲁棒性,比较不同算法的优缺点,针对基于DCT和DFT的视频盲水印算法进行了研究。研究并实现了3种基于DCT的视频水印算法和1种基于DFT的视频水印算法。通过实验,统计它们的透明性和鲁棒性。...
  • 基于DCT变换的QWT域改进的图像盲水印算法
  • 介绍了一种基于离散余弦变换域(DCT)中频系数置换的盲水印算法,用该算法对数字水印进行了自适应嵌入方法研究。该算法突破了数字水印的加性算法、乘性算法等传统的水印嵌入方法;解决了被提取水印中含有原始图像DCT...
  • 提出一种基于DCT变换的数字图像盲水印算法,通过调整DCT域选定中频的大小关系嵌入水印,易于实现。仿真试验证明本算法能够抵御剪切、噪音和JPEG压缩失真,具有良好的不可见性和鲁棒性。
  • 基于DWT-DCT的非物质文化遗产保护盲水印算法
  • 基于3D-DCT彩色图像水印方案
  • DCT数字水印嵌入与提取过程 还有几种攻击方式 毕业设计可以使用 各位毕业设计课题相关的可以看看 有不明白的地方可以留言 我看到会尽快回答
  • 一种DCT变换域图像水印算法 图书馆数据库资料 不错的
  • 提出了一种在分块DCT的次低频交流系数中,利用奇偶特性和JPEG量化系数嵌入有含义的8位灰度水印图像,以实现提取的算法,并通过PN序列加密来保证水印的安全性。实验结果表明,该算法对于JPEG有损压缩、图像剪切等...
  • 基于DCT域的数字图像盲水印算法研究,王红 程永强,,数字水印是一种有效的数字产品版权保护和数据安全维护技术,它将具有特定意义的标记即水印,利用数字嵌入的方法隐藏在数字图像、
  • 数字盲水印

    2014-03-23 21:18:21
    dct数字盲水印 提出一种基于离散余弦变换(DCT)。
  • 这是一篇关于信息隐藏(数字水印)方面的论文,基于HVS实现的。
  • 从改进的角度,提出一种基于宿主图像的DCT域嵌入较大分辨率灰度级数字盲水印的优化算法。该算法采用视觉频率、图像灰度增强和灰度图像门限值JND量化选取DCT子块系数,对嵌入宿主图像的较大分辨率256级灰度水印先行压缩...
  • 提出一种新的灰度级水印算法。它充分利用离散小波变换的多分辨率特性和离散余弦变换的能量压缩能力,将预处理后的灰度水印图像隐藏在原始图像DCT系数量化值的奇偶性中,在水印的提取过程中不需要原始图像的参与。...
  • 基于DCT变换的半脆弱检测水印
  • 采用Logistic混沌映射和Cheby- chev混沌映射生成复合混沌序列置换像素的值,Arnold变换置乱像素的位置,并根据离散余弦变换(discrete cosine transform, DCT)系数计算水印嵌入强度因子,设计了彩色水印的嵌入与检...
  • 利用分块DCT系数的周期特性,结合Z字形编码置乱技术和JPEG量化系数,提出了一种在分块DCT中频交流系数中嵌入有含义二值水印图像,以实现检测的水印方案。实验结果表明,该算法对图像剪切、JPEG有损压缩、中值滤波...
  • 数字图像水印的一种算法——基于离散余弦变换的检测水印算法,属于入门级的
  • 为了研究Job-shop调度问题,分析了调度结果和调度过程,认为传统Job-shop调度模型的调度过程,实质是减少并减小空闲时间的组合优化过程,而且不同空闲时间对调度结果的影响程度不同。据此提出了最小化空闲时间的两个处理...
  • 随着网络技术和多媒体技术的飞速发展,如何保护多媒体信息的安全已成为国际上研究的热门...文中简介了目前主流数字水印算法,给出了DCT域数字盲水印算法。该水印算法不可见性较好,对JPEG压缩,噪声,有较好的鲁棒性。
  • 水印算法的相关说明: 嵌入图片: 水印图:只能是64 * 64的二值图 原图:只能是512 * 512的图片 嵌入数字: 数字:只能是0或者1的数字嵌入到图片中,可以嵌入64 * 64=4096个0或者1 原图:只能是512 * 512的图片 改...

    此水印算法的相关说明:

    嵌入图片:
    水印图:只能是64 * 64的二值图
    原图:只能是512 * 512的图片

    嵌入数字:
    数字:只能是0或者1的数字嵌入到图片中,可以嵌入64 * 64=4096个0或者1
    原图:只能是512 * 512的图片

    改算法目前只能抵抗:
    亮度,压缩,对比度,饱和度,缩放这些攻击。

    攻击算法实现

    对于缩放而言需要注意的是,任何缩放,不管它缩放的比例是多少,我们在最后提取水印的时候必须将其变成512*512的图片,这样才能提取水印成功。

    因为在做数字水印时,我们这个项目,不需要考虑到,裁剪这个攻击所以就没有对算法进行优化,所以不能抵抗裁剪攻击。

    所需工具:
    opencv-410

    算法如下:

    创建工具类 ImgWatermarkUtil.java

    package ImageWaterMark;
    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import javax.imageio.ImageIO;
    import org.opencv.core.Core;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.core.Size;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    
    public class ImageWaterMarkUtil {
    	   static{
    	        //加载opencv动态库
    	        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    	    }
    	    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    	}
    
    	
    	/**
    	 * 嵌入水印信息
    	 * @param image:原图
    	 * @param watermark:水印信息
    	 * @param p:嵌入强度
    	 */
    	public static Mat addImageWatermarkWithText(Mat image, int[][] watermark,double p) {
    		List<Mat> allPlanes = new ArrayList<Mat>(); 
    		
    		Mat Ycbcr=new Mat(image.rows(),image.cols(),CvType.CV_8UC1);
    		Imgproc.cvtColor(image, Ycbcr,Imgproc.COLOR_RGB2YCrCb);	
    		Core.split(image, allPlanes);
    		//获取YMat矩阵
    		Mat YMat = allPlanes.get(0);
    
    		//分成4096块
    		for(int i=0;i<watermark.length;i++) {
    			for(int j=0;j<watermark[0].length;j++) {
    				
    				//block 表示分块 而且为 方阵
    
    				int length = image.rows()/watermark.length;
    				Mat block = null;
    				//提取每个分块
    				block = getImageValue(YMat,i,j,length);
    				
    				
    						
    				double[] a = new double[1];				
    				double[] c = new double[1];
    						
    				int x1 = 1, y1 = 2;
    				int x2 = 2, y2 = 1;
    				
    				a = block.get(x1,y1);
    				c = block.get(x2,y2);
    			
    				//对分块进行DCT变换
    				Core.dct(block, block);
    			
    				a = block.get(x1,y1);
    				c = block.get(x2,y2);
    
    				if(watermark[i][j] == 1) {	
    					block.put(x1,y1, p);
    					block.put(x2,y2, 0);
    				}
    				
    				
    				if(watermark[i][j] == 0) {	
    					block.put(x1,y1, 0);
    					block.put(x2,y2, p);
    				}
    			
    			
    			//对上面分块进行IDCT变换
    			Core.idct(block, block);
    			for(int m=0;m<length;m++) {
    					for(int t=0;t<length;t++) {
    						double[] e = block.get(m, t);
    						YMat.put(i*length + m,j*length + t, e);
    					}
    				}
    			}
    	
    		}
    		
    		Mat imageOut = new Mat();
    		Core.merge(allPlanes,imageOut);
    		
    		return imageOut;
    	}
    	
    	/**
    	 * 提取水印信息
    	 * @param image:带提取的图片
    	 * @return int[][]
    	 */
    	public static int[][] getImageWatermarkWithText(Mat image,double p) {
    		
    		List<Mat> allPlanes = new ArrayList<Mat>();
    
    		
    		Mat Ycbcr=new Mat(image.rows(),image.cols(),CvType.CV_8UC1);
    		Imgproc.cvtColor(image, Ycbcr,Imgproc.COLOR_RGB2YCrCb);	
    		Core.split(image, allPlanes);
    		
    		Mat YMat = allPlanes.get(0);
    		
    		int watermark[][] = new int[64][64];
    
    				
    		//分成64块,提取每块嵌入的水印信息
    		for(int i=0;i<64;i++) {
    			for(int j=0;j<64;j++) {
    				//block 表示分块 而且为 方阵
    				int length = image.rows()/watermark.length;
    				Mat block = null;
    				//提取每个分块
    				block = getImageValue(YMat,i,j,length);
    
    
    				//对分块进行DCT变换
    				Core.dct(block, block);
    				//用于容纳DCT系数
    				double[] a = new double[1];
    				double[] c = new double[1];
    
    				int x1 = 1, y1 = 2;
    				int x2 = 2, y2 = 1;
    				
    				a = block.get(x1,y1);
    				c = block.get(x2,y2);
    				
    				if(a[0]>=c[0])
    					watermark[i][j] = 1;			 			
    			}			
    	}
    		return watermark;
    	}
    	
    	/**
    	 * 提取每个分块
    	 * @param YMat:原分块
    	 * @param x:x与y联合表示第几个块
    	 * @param y:x与y联合表示第几个块
    	 * @param length:每个块的长度
    	 * @return
    	 */
    	public static Mat getImageValue(Mat YMat,int x,int y,int length) {
    		Mat mat = new Mat(length,length,CvType.CV_32F);
    		for(int i=0;i<length;i++) {
    			for(int j=0;j<length;j++) {
    				
    				double[] temp = YMat.get(x*length+i, y*length+j); 
    				mat.put(i, j, temp);
    			}
    		}
    		return mat;
    	}
    	
    	/**
    	 * 获取二值图的信息
    	 */
    	public static int[][] getInformationOfBinaryGraph(String srcPath){
    		int[][] waterMark = new int[64][64];
    
    		Mat mat = Imgcodecs.imread(srcPath);
    		
    		int width = 64;
    		int height = 64;
    		double a[] = new double[3];
    		for(int i=0;i<width;i++) {
    			for(int j=0;j<height;j++) {
    				a = mat.get(i, j);
    				if((int)a[0] == 255)
    					waterMark[i][j] = 1;
    				else 
    					waterMark[i][j] = 0;
    			}
    		}
    
    		return waterMark;
    	}
    	
    	
    	/**
    	 *将水印信息的二维数组转换为一张图片
    	 */
    	public static void matrixToBinaryPhoto(int[][] watermark,String dstPath) {
    		
    		int width = 64,height = 64;	
    		Mat binaryPhoto  = new Mat(width,height,Imgproc.THRESH_BINARY);
    		
    		double a[] = new double[] {255,255,255};
    		double b[] = new double[] {0,0,0};
    		
    		for(int i=0;i<width;i++) {
    			for(int j=0;j<height;j++) {				
    				if(watermark[i][j] == 1)
    					binaryPhoto.put(i, j, a);
    				else
    					binaryPhoto.put(i, j, b);
    			}
    		}	
    		Imgcodecs.imwrite(dstPath, binaryPhoto);
    	}
    	
    	
    	/**
    	 * 将一张图片压缩成一张64x64的二值图
    	 * @param srcPath
    	 * @param dstPath
    	 */
    	public static String getBinaryPhoto(String srcPath,String dstPath)  {
    		
    		srcPath = thumbnail(srcPath, dstPath,64,64);
    		
    		//得到原图
    		File file = new File(srcPath);
    		BufferedImage image = null;
    		try {
    			image = ImageIO.read(file);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		int width = image.getWidth();
    		int height = image.getHeight();
    		//创建原图的二值图
    		BufferedImage binaryPhoto = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_BINARY);
    		int min = new Color(0,0,0).getRGB();
    		int max = new Color(255,255,255).getRGB();
    		//判断标记
    		int flag = 170;
    		for(int i=0;i<width;i++) {
    			for(int j=0;j<height;j++) {				
    				//像素
    				int pixel = image.getRGB(i, j);
    				//得到 rgb通道对应的元素
    				int r,g,b;
    				r = (pixel & 0xff0000) >> 16;
    				g = (pixel & 0xff00) >> 8;
    				b = (pixel & 0xff);				
    				int avg = (r + g + b)/3;			
    				if(avg <= flag)
    					binaryPhoto.setRGB(i, j, min);
    				else
    					binaryPhoto.setRGB(i, j, max);		
    			}
    		}
    		try {
    			ImageIO.write(binaryPhoto, "bmp", new File(dstPath));
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}		
    		return dstPath;
    	}
    	
    	
    	
        /**
         * 将图片变成指定大小的图片
         */
        public static String thumbnail(String srcImagePath, String desImagePath,int w,int h) {
    
            Mat src = Imgcodecs.imread(srcImagePath);
            Mat dst = src.clone();
            Imgproc.resize(src, dst, new Size(w, h));
            Imgcodecs.imwrite(desImagePath, dst);
            return desImagePath; 
        }
    }
    

    测试 ImgWatermarkUtil.java

    package ImageWaterMark;
    
    import java.io.IOException;
    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.imgcodecs.Imgcodecs;
    
    public class ImageWaterMarkMain {
    
        static{
            //加载opencv动态库
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        }
        
        /**
         * 嵌入图片的盲水印
         */
        public static void photo() {
        	
        	//用于存储水印信息
        	int[][] watermark = new int[64][64];
        	
        	//原图
        	String src = "C:\\Users\\Fenix\\Desktop\\cxf\\stzz.bmp";
        	//嵌入后的图的保存路径
        	String dst = "C:\\Users\\Fenix\\Desktop\\cxf\\stzz-out.bmp";
        	//水印路径
        	String waterMarkPath = "C:\\Users\\Fenix\\Desktop\\cxf\\sign.bmp";
        	
        	//保存提取到的图片水印
        	String waterDstPath = "C:\\Users\\Fenix\\Desktop\\cxf\\sign-out.bmp";
        	
        	//嵌入强度
        	int p = 75;
        	
        	
        	//---------嵌入图片水印信息-------------
        	
        	//将水印图片中的Y通道提取出来,保存到watermark数组中
        	watermark = ImageWaterMarkUtil.getInformationOfBinaryGraph(waterMarkPath);
        	
        	//读取原图
        	Mat image = Imgcodecs.imread(src);
        	
        	//保存嵌入后的图
        	Mat imageOut = ImageWaterMarkUtil.addImageWatermarkWithText(image,watermark,p);
        	Imgcodecs.imwrite(dst, imageOut);
        	
        	
        	//---------提取图片水印信息-------------
        	
        	//读取嵌入后的图
        	Mat watermarkOut = Imgcodecs.imread(dst);
        	
        	//得到水印的数组信息
        	int[][] watermark_out = ImageWaterMarkUtil.getImageWatermarkWithText(watermarkOut, p);
        	
        	//将水印的数组信息转化为图片
        	ImageWaterMarkUtil.matrixToBinaryPhoto(watermark_out, waterDstPath);
        }
        
        
        /**
         * 嵌入数字的盲水印
         */
        public static void number() {
        	
        	//创建数字水印
        	int[][] watermark = new int[64][64];
        	
        	for(int i=0;i<64;i++) {
        		for(int j=0;j<64;j++) {
        			if(i%2 == 0)
        			watermark[i][j] = 1;	
        		}
        	}
        	
        	//原图
        	String src = "C:\\Users\\Fenix\\Desktop\\cxf\\stzz.bmp";
        	//嵌入后的图的保存路径
        	String dst = "C:\\Users\\Fenix\\Desktop\\cxf\\stzz-out.bmp";
        	
        	//嵌入强度
        	int p = 75;
        	
        	//---------嵌入数字水印信息-------------
        	
        	//读取原图
        	Mat image = Imgcodecs.imread(src);
        	//保存嵌入后的图
        	Mat imageOut = ImageWaterMarkUtil.addImageWatermarkWithText(image,watermark,p);  	
        	Imgcodecs.imwrite(dst, imageOut);
        	
        	
        	//---------提取数字水印信息-------------
        	
        	//读取嵌入后的图
        	Mat watermarkOut = Imgcodecs.imread(dst);
        	//得到水印的数组信息
        	int[][] watermark_out = ImageWaterMarkUtil.getImageWatermarkWithText(watermarkOut, p);
        	
        	
        	//计算提取率
        	int val = 0;
        	for(int i=0;i<64;i++) {
        		for(int j=0;j<64;j++) {
        			
        			if(watermark_out[i][j] == watermark[i][j])
        				val++;
        		}
        	}
        	
        	System.out.println("提取率: "+(val * 1.0 / 4096));
    
        }
        
        
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		
    		//嵌入图片的盲水印
    		//photo();
    		//嵌入数字的盲水印
    		number();
    		
    		//如果没有64*64的二值图可调用方法
    		//ImageWaterMarkUtil.getBinaryPhoto(srcPath, dstPath);
    		
    		//如果没有512*512的原图可调用方法
    		//ImageWaterMarkUtil.thumbnail(srcImagePath, desImagePath, 512, 512);
    		
    		
    	}
    }
    

    在这里呢?我之展示嵌入图片的效果:
    原图
    在这里插入图片描述
    水印图:
    在这里插入图片描述
    嵌入后的图:
    在这里插入图片描述
    提取后的水印图:
    在这里插入图片描述

    在这里进一步讲解这个算法可以改进的地方。

    我们可以看到在这个算法当中有一个嵌入强度这个因素

    int p = 75;
    在这里我想说的是,改变强度p的大小,那么会影响嵌入后的效果,当p值越大,那么鲁棒性越强,
    但嵌入后的图片效果越差,当p值越小,那么鲁棒性越弱,但嵌入后的图片效果越强,就是经过许多测试,我感觉在 75 左右的效果比较好。所以这是这个算法第一个可以改进的地方

    接着我们看看另一个可以改进的地方:
    如下所示:
    在 ImgWatermarkUtil.java 中,
    addImageWatermarkWithText( )方法中

    int x1 = 1, y1 = 2;
    int x2 = 2, y2 = 1;

    可以改变这两个坐标的值,同时改变了这里后,也需要改变,
    getImageWatermarkWithText( ) 方法中

    int x1 = 1, y1 = 2;
    int x2 = 2, y2 = 1;

    为什么?改变这两个坐标的值,可以提高性能呢?可以看看我写的这篇文章?

    数字水印的处理心得

    然后呢,我们在这个算法中对于数字而言,我们只能嵌入和提取0或者1,那么要怎样才能嵌入汉字呢?

    我觉得我们可以对汉字进行编码,将一个汉字对应成一段二进制数,然后将二进数嵌入到图片中去,提取也是这样,提取出相应的二进制数,然后找到对应的汉字就可以了。

    我们如何再次增加这个算法嵌入的容量呢?
    这个我们只能将原图变大,在这个算法中原图是512 * 512 ,每 8 * 8 对应一个0或者1,所以只有增大原图的大小,从而就可以提高算法的容量。

    最后呢?我说说这个算法怎样才能抵抗裁剪,或者说抵抗裁剪怎么实现?

    在这里我用64 * 64 的二值图作为举例,抵抗裁剪,我们可以先将 64 * 64 的二值图嵌入到原图,然后我们将得到 嵌入后的图片,然后我们在将这个嵌入后的图片 再次 嵌入 64 * 64 的二值图,但是,这个时候,的 64 * 64 的二值图,需要进行一定的处理,怎么处理呢?就是将 二值图 得到的二维矩阵 进行 转置 操作,然后在嵌入,就可以了。

    总之就是, 8 * 8 的像素块需要,改变 4 个DCT系数(原来只是改变2个DCT系数),那么有没有什么方法可以改进呢?

    有,我们可以将其改进到 改变2个DCT系数,就是,找一个点作为中间点,改变另外两个DCT系数(这里a,b表示)即可,

    对于a点:
    如果要嵌入0,则让a的DCT系数 = 中间点的DCT系数 - P(嵌入强度(常数)),
    如果要嵌入1,则让a的DCT系数 = 中间点的DCT系数 + P(嵌入强度(常数))。

    对于b点:
    如果要嵌入0,则让b的DCT系数 = 中间点的DCT系数 - P(嵌入强度(常数)),
    如果要嵌入1,则让b的DCT系数 = 中间点的DCT系数 + P(嵌入强度(常数))。

    提取就是,
    比较相应DCT的大小,若大于中间点的DCT系数,表示1,若小于中间点的DCT系数,表示0

    这就是可以抗裁剪的大致实现过程。

    最后呢?
    我在来说一说,我的这个算法是,改变了2个DCT系数,如果不需要抵抗裁剪攻击的话,可以向上面抵抗裁剪攻击那样进行优化,可以优化到改变1个DCT系数,

    小彩蛋
    这是这个算法 p = 75 时在亮度,压缩,对比度,饱和度,缩放这些攻击下,的提取效果图。因为图片过多,所以我就不再展示,所以就用百度云吧!!!
    百度云,提取码是,uiru

    如果觉得对你有帮助的话,那就点个赞吧!!!

    展开全文
  • 针对常规的图像水印算法不能很好地实现水印不可感知性和鲁棒性折中的问题, 给出了一种最优均值量化盲水印算法。该算法首先对水印图像进行Arnold置乱, 提高了水印的安全性; 然后将载体图像进行8×8分块DCT(离散余弦...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 219
精华内容 87
关键字:

dct盲水印