├── README.md └── 数字水印的嵌入与提取原型 ├── Evaluation.py ├── Evaluation.ui ├── HYASUO.m ├── QImageToNumpy.py ├── __pycache__ ├── Evaluation.cpython-36.pyc ├── QImageToNumpy.cpython-36.pyc └── mainUI.cpython-36.pyc ├── attack.m ├── dct.m ├── dwt.m ├── dwt.mat ├── main.py ├── mainUI.py ├── mainUI.ui ├── nc.m ├── picture ├── _copyright_small.bmp ├── baboon.ppm ├── carrier_image.jpg └── flag.jpg └── ssim.m /README.md: -------------------------------------------------------------------------------- 1 | # Digital-Watermark-use-python-and-matlab 2 | Digital Image Watermarking use matlab(DWT,DCT), GUI use python 3 | 4 | This repository use python call matlab to realize digital watermarking. Transform data form is the key point of the project. 5 | 6 | DWT can process RGB image. 7 | when DCT process RGB image,firstly, make RGB to grey, so embed grey image better. 8 | 9 | # STEP 10 | You can run the file 'main.py' to start the project. 11 | 12 | 1.choose carrier image and message image 13 | 14 | 2.choose attack method 15 | 16 | 3.click one button(DWT,DCT) 17 | 18 | PS:Carrier image can choose baboon.ppm or carrier_image.jpg, message can choose flag.jpg or _copyright_small.bmp 19 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/Evaluation.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'Evaluation.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.13.0 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | 10 | from PyQt5 import QtCore, QtGui, QtWidgets 11 | from PyQt5.QtWidgets import QHeaderView, QAbstractItemView 12 | 13 | 14 | class Ui_Dialog(object): 15 | def setupUi(self, Dialog): 16 | Dialog.setObjectName("Dialog") 17 | Dialog.resize(322, 90) 18 | self.tableWidget = QtWidgets.QTableWidget(Dialog) 19 | self.tableWidget.setGeometry(QtCore.QRect(20, 30, 281, 81)) 20 | self.tableWidget.setStyleSheet("") 21 | self.tableWidget.setObjectName("tableWidget") 22 | self.tableWidget.setColumnCount(3) 23 | self.tableWidget.setRowCount(2) 24 | item = QtWidgets.QTableWidgetItem() 25 | self.tableWidget.setVerticalHeaderItem(0, item) 26 | item = QtWidgets.QTableWidgetItem() 27 | self.tableWidget.setVerticalHeaderItem(1, item) 28 | item = QtWidgets.QTableWidgetItem() 29 | item.setBackground(QtGui.QColor(170, 255, 255)) 30 | self.tableWidget.setHorizontalHeaderItem(0, item) 31 | item = QtWidgets.QTableWidgetItem() 32 | item.setBackground(QtGui.QColor(170, 255, 255)) 33 | self.tableWidget.setHorizontalHeaderItem(1, item) 34 | item = QtWidgets.QTableWidgetItem() 35 | item.setBackground(QtGui.QColor(170, 255, 255)) 36 | self.tableWidget.setHorizontalHeaderItem(2, item) 37 | self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) 38 | # self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) 39 | self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) 40 | 41 | 42 | self.retranslateUi(Dialog) 43 | QtCore.QMetaObject.connectSlotsByName(Dialog) 44 | 45 | def retranslateUi(self, Dialog): 46 | _translate = QtCore.QCoreApplication.translate 47 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 48 | item = self.tableWidget.verticalHeaderItem(0) 49 | item.setText(_translate("Dialog", "未攻击")) 50 | item = self.tableWidget.verticalHeaderItem(1) 51 | item.setText(_translate("Dialog", "攻击后")) 52 | item = self.tableWidget.horizontalHeaderItem(0) 53 | item.setText(_translate("Dialog", "PSNR")) 54 | item = self.tableWidget.horizontalHeaderItem(1) 55 | item.setText(_translate("Dialog", "NCC")) 56 | item = self.tableWidget.horizontalHeaderItem(2) 57 | item.setText(_translate("Dialog", "MSSIM")) 58 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/Evaluation.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 326 10 | 151 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 20 | 30 21 | 281 22 | 81 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 未攻击 31 | 32 | 33 | 34 | 35 | 攻击后 36 | 37 | 38 | 39 | 40 | PSNR 41 | 42 | 43 | 44 | 170 45 | 255 46 | 255 47 | 48 | 49 | 50 | 51 | 52 | NCC 53 | 54 | 55 | 56 | 170 57 | 255 58 | 255 59 | 60 | 61 | 62 | 63 | 64 | MSSIM 65 | 66 | 67 | 68 | 170 69 | 255 70 | 255 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/HYASUO.m: -------------------------------------------------------------------------------- 1 | function result=HYASUO(I) 2 | yuzhi=50; 3 | A=I(:,:,1); 4 | B=I(:,:,2); 5 | C=I(:,:,3); 6 | [c,k]=size(A); 7 | for i=1:c 8 | for j=1:k 9 | if A(i,j)<=yuzhi 10 | A(i,j)=0; 11 | end 12 | if B(i,j)<=yuzhi 13 | B(i,j)=0; 14 | end 15 | if C(i,j)<=yuzhi 16 | C(i,j)=0; 17 | end 18 | end 19 | end 20 | result=cat(3,A,B,C); 21 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/QImageToNumpy.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtWidgets,QtCore,QtGui 2 | from PyQt5.QtGui import * 3 | 4 | import numpy as np 5 | 6 | def QImageToCvMat(incomingImage): 7 | ''' Converts a QImage into an opencv MAT format ''' 8 | 9 | incomingImage = incomingImage.convertToFormat(QtGui.QImage.Format.Format_RGB888) 10 | 11 | width = incomingImage.width() 12 | height = incomingImage.height() 13 | 14 | ptr = incomingImage.bits() 15 | ptr.setsize(height * width * 3) 16 | arr = np.frombuffer(ptr, np.uint8).reshape((height, width, 3)) 17 | return arr 18 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/__pycache__/Evaluation.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/__pycache__/Evaluation.cpython-36.pyc -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/__pycache__/QImageToNumpy.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/__pycache__/QImageToNumpy.cpython-36.pyc -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/__pycache__/mainUI.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/__pycache__/mainUI.cpython-36.pyc -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/attack.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/attack.m -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/dct.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/dct.m -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/dwt.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/dwt.m -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/dwt.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/dwt.mat -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/main.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import sys 3 | import os 4 | from PyQt5 import QtWidgets,QtCore,QtGui 5 | from PyQt5.QtGui import * 6 | from PyQt5.QtWidgets import * 7 | from PyQt5.QtCore import * 8 | from matlab import engine 9 | 10 | from mainUI import * 11 | import mainUI 12 | import Evaluation 13 | 14 | import matlab 15 | import matlab.engine 16 | 17 | import numpy as np 18 | 19 | import qimage2ndarray 20 | from QImageToNumpy import QImageToCvMat 21 | 22 | 23 | # 点击各方法按钮弹出的评价值表格 24 | class ChildWindow(QDialog,Evaluation.Ui_Dialog,QTableWidget): 25 | def __init__(self): 26 | QDialog.__init__(self) 27 | self.dialog=Evaluation.Ui_Dialog() 28 | self.dialog.setupUi(self) 29 | 30 | 31 | 32 | class MainCode(QMainWindow,mainUI.Ui_MainWindow): 33 | def __init__(self): 34 | QMainWindow.__init__(self) 35 | mainUI.Ui_MainWindow.__init__(self) 36 | self.setupUi(self) 37 | self.img_open.clicked.connect(self.on_open1) 38 | self.message_open.clicked.connect(self.on_open2) 39 | self.DWT.clicked.connect(self.dwt_exc) 40 | self.DCT.clicked.connect(self.dct_exc) 41 | 42 | 43 | 44 | # 选择载体图像 45 | def on_open1(self): 46 | imgName1, imgType = QFileDialog.getOpenFileName(self, "Pick an Image File", "./picture/", "*.jpg;;*.png;;*.ppm;;All Files(*)") 47 | jpg1 = QtGui.QPixmap(imgName1) 48 | self.img1.setScaledContents(True) 49 | self.img1.setPixmap(jpg1) 50 | name=imgName1[45:] 51 | self.cover_img.setPlainText(name) 52 | 53 | 54 | # 选择水印图像 55 | def on_open2(self): 56 | imgName2,imgType = QFileDialog.getOpenFileName(self, 'Pick an Image File', "./picture/", "*.bmp;;*.jpg;;*.png;;All Files(*)") 57 | jpg2 = QtGui.QPixmap(imgName2) 58 | self.img2.setScaledContents(True) 59 | self.img2.setPixmap(jpg2) 60 | name = imgName2[45:] 61 | self.message_img.setPlainText(name) 62 | 63 | 64 | 65 | # 基于DWT的水印嵌入与提取 66 | def dwt_exc(self): 67 | # get picture from QLabel 68 | image1 = self.img1.pixmap().toImage() 69 | image2 = self.img2.pixmap().toImage() 70 | # QImage to array,otherwise cannot use matlab 71 | cover = QImageToCvMat(image1) 72 | message1 = QImageToCvMat(image2) 73 | height = message1.shape[0] 74 | width = message1.shape[1] 75 | cover_object = matlab.uint8(cover.tolist()) 76 | message = matlab.uint8(message1.tolist()) 77 | # var is number of attact function 78 | var = self.comboBox.currentIndex() + 1 79 | # 调用matlab 80 | engine = matlab.engine.start_matlab() 81 | watermrkd_img, recmessage,attack_image, attack_message, PSNR, NCC, MSSIM,PSNR_a, NCC_a, MSSIM_a=engine.dwt(cover_object, message, height,width,var, nargout=10) 82 | watermrkd_img = np.array(watermrkd_img) 83 | recmessage = np.array(recmessage) 84 | attack_image = np.array(attack_image) 85 | attack_message = np.array(attack_message) 86 | # transform picture from matlab (array to qimage), and show on the GUI 87 | jpg3 = qimage2ndarray.array2qimage(watermrkd_img) 88 | watermrkd = QtGui.QPixmap(jpg3) 89 | self.img3.setScaledContents(True) 90 | self.img3.setPixmap(watermrkd) 91 | jpg4 = qimage2ndarray.array2qimage(recmessage) 92 | rec = QtGui.QPixmap(jpg4) 93 | self.img4.setScaledContents(True) 94 | self.img4.setPixmap(rec) 95 | jpg5 = qimage2ndarray.array2qimage(attack_image) 96 | atk = QtGui.QPixmap(jpg5) 97 | self.img5.setScaledContents(True) 98 | self.img5.setPixmap(atk) 99 | jpg6 = qimage2ndarray.array2qimage(attack_message) 100 | atk_msg = QtGui.QPixmap(jpg6) 101 | self.img6.setScaledContents(True) 102 | self.img6.setPixmap(atk_msg) 103 | # 弹出评价值表格 104 | self.child = ChildWindow() 105 | self.child.dialog.tableWidget.setItem(0, 0, QTableWidgetItem("%.8f" % PSNR)) 106 | self.child.dialog.tableWidget.setItem(0, 1, QTableWidgetItem("%.8f" % NCC)) 107 | self.child.dialog.tableWidget.setItem(0, 2, QTableWidgetItem("%.8f" % MSSIM)) 108 | self.child.dialog.tableWidget.setItem(1, 0, QTableWidgetItem("%.8f" % PSNR_a)) 109 | self.child.dialog.tableWidget.setItem(1, 1, QTableWidgetItem("%.8f" % NCC_a)) 110 | self.child.dialog.tableWidget.setItem(1, 2, QTableWidgetItem("%.8f" % MSSIM_a)) 111 | layout = QHBoxLayout() 112 | layout.addWidget(self.child.dialog.tableWidget) 113 | self.child.setLayout(layout) 114 | self.child.show() 115 | 116 | 117 | 118 | # 基于DCT的水印嵌入与提取 119 | def dct_exc(self): 120 | image1 = self.img1.pixmap().toImage() 121 | image2 = self.img2.pixmap().toImage() 122 | # 获取QLabel上的图片并转成numpy格式,再转成list,传入matlab 123 | cover=QImageToCvMat(image1) 124 | message1=QImageToCvMat(image2) 125 | height=message1.shape[0] 126 | width=message1.shape[1] 127 | cover_object = matlab.uint8(cover.tolist()) 128 | message = matlab.uint8(message1.tolist()) 129 | var=self.comboBox.currentIndex()+1 130 | # 调用matlab 131 | engine = matlab.engine.start_matlab() 132 | watermrkd_img, recmessage, attack_image, attack_message, PSNR, NCC, MSSIM, PSNR_a, NCC_a, MSSIM_a= engine.dct(cover_object, message, height, width, var, nargout=10) 133 | watermrkd_img=np.array(watermrkd_img) 134 | recmessage = np.array(recmessage) 135 | attack_image = np.array(attack_image) 136 | attack_message = np.array(attack_message) 137 | # transform picture from matlab (array to qimage), and show on the GUI 138 | jpg3=qimage2ndarray.array2qimage(watermrkd_img) 139 | watermrkd = QtGui.QPixmap(jpg3) 140 | self.img3.setScaledContents(True) 141 | self.img3.setPixmap(watermrkd) 142 | jpg4 = qimage2ndarray.array2qimage(recmessage) 143 | rec = QtGui.QPixmap(jpg4) 144 | self.img4.setScaledContents(True) 145 | self.img4.setPixmap(rec) 146 | jpg5 = qimage2ndarray.array2qimage(attack_image) 147 | atk = QtGui.QPixmap(jpg5) 148 | self.img5.setScaledContents(True) 149 | self.img5.setPixmap(atk) 150 | jpg6 = qimage2ndarray.array2qimage(attack_message) 151 | atk_msg = QtGui.QPixmap(jpg6) 152 | self.img6.setScaledContents(True) 153 | self.img6.setPixmap(atk_msg) 154 | # 弹出评价值表格 155 | self.child=ChildWindow() 156 | self.child.dialog.tableWidget.setItem(0, 0, QTableWidgetItem("%.8f" % PSNR)) 157 | self.child.dialog.tableWidget.setItem(0, 1, QTableWidgetItem("%.8f" % NCC)) 158 | self.child.dialog.tableWidget.setItem(0, 2, QTableWidgetItem("%.8f" % MSSIM)) 159 | self.child.dialog.tableWidget.setItem(1, 0, QTableWidgetItem("%.8f" % PSNR_a)) 160 | self.child.dialog.tableWidget.setItem(1, 1, QTableWidgetItem("%.8f" % NCC_a)) 161 | self.child.dialog.tableWidget.setItem(1, 2, QTableWidgetItem("%.8f" % MSSIM_a)) 162 | layout=QHBoxLayout() 163 | layout.addWidget(self.child.dialog.tableWidget) 164 | self.child.setLayout(layout) 165 | self.child.show() 166 | 167 | 168 | 169 | if __name__=="__main__": 170 | 171 | QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) 172 | app=QtWidgets.QApplication(sys.argv) 173 | 174 | my=MainCode() 175 | my.show() 176 | sys.exit(app.exec()) -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/mainUI.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'mainUI.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.13.0 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | 10 | from PyQt5 import QtCore, QtGui, QtWidgets 11 | 12 | 13 | class Ui_MainWindow(object): 14 | def setupUi(self, MainWindow): 15 | MainWindow.setObjectName("MainWindow") 16 | MainWindow.setEnabled(True) 17 | MainWindow.resize(686, 380) 18 | self.centralwidget = QtWidgets.QWidget(MainWindow) 19 | self.centralwidget.setObjectName("centralwidget") 20 | self.cover_img = QtWidgets.QTextEdit(self.centralwidget) 21 | self.cover_img.setGeometry(QtCore.QRect(10, 30, 111, 21)) 22 | self.cover_img.setObjectName("cover_img") 23 | self.img_open = QtWidgets.QPushButton(self.centralwidget) 24 | self.img_open.setGeometry(QtCore.QRect(130, 30, 41, 21)) 25 | self.img_open.setCheckable(False) 26 | self.img_open.setObjectName("img_open") 27 | self.label = QtWidgets.QLabel(self.centralwidget) 28 | self.label.setGeometry(QtCore.QRect(30, 10, 61, 16)) 29 | self.label.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 30 | "background-color: rgb(170, 255, 255);") 31 | self.label.setObjectName("label") 32 | self.label_2 = QtWidgets.QLabel(self.centralwidget) 33 | self.label_2.setGeometry(QtCore.QRect(30, 70, 61, 16)) 34 | self.label_2.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 35 | "background-color: rgb(170, 255, 255);") 36 | self.label_2.setObjectName("label_2") 37 | self.message_img = QtWidgets.QTextEdit(self.centralwidget) 38 | self.message_img.setGeometry(QtCore.QRect(10, 90, 111, 21)) 39 | self.message_img.setObjectName("message_img") 40 | self.message_open = QtWidgets.QPushButton(self.centralwidget) 41 | self.message_open.setGeometry(QtCore.QRect(130, 90, 41, 21)) 42 | self.message_open.setObjectName("message_open") 43 | self.label_3 = QtWidgets.QLabel(self.centralwidget) 44 | self.label_3.setGeometry(QtCore.QRect(20, 130, 101, 16)) 45 | self.label_3.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 46 | "background-color: rgb(170, 255, 255);") 47 | self.label_3.setObjectName("label_3") 48 | self.comboBox = QtWidgets.QComboBox(self.centralwidget) 49 | self.comboBox.setGeometry(QtCore.QRect(10, 150, 61, 22)) 50 | self.comboBox.setObjectName("comboBox") 51 | self.comboBox.addItem("") 52 | self.comboBox.addItem("") 53 | self.comboBox.addItem("") 54 | self.comboBox.addItem("") 55 | self.comboBox.addItem("") 56 | self.DWT = QtWidgets.QPushButton(self.centralwidget) 57 | self.DWT.setGeometry(QtCore.QRect(10, 200, 41, 21)) 58 | self.DWT.setObjectName("DWT") 59 | self.label_4 = QtWidgets.QLabel(self.centralwidget) 60 | self.label_4.setGeometry(QtCore.QRect(240, 10, 61, 16)) 61 | self.label_4.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 62 | "background-color: rgb(170, 255, 255);") 63 | self.label_4.setObjectName("label_4") 64 | self.label_5 = QtWidgets.QLabel(self.centralwidget) 65 | self.label_5.setGeometry(QtCore.QRect(400, 10, 61, 16)) 66 | self.label_5.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 67 | "background-color: rgb(170, 255, 255);") 68 | self.label_5.setObjectName("label_5") 69 | self.label_7 = QtWidgets.QLabel(self.centralwidget) 70 | self.label_7.setGeometry(QtCore.QRect(540, 10, 91, 16)) 71 | self.label_7.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 72 | "background-color: rgb(170, 255, 255);") 73 | self.label_7.setObjectName("label_7") 74 | self.label_8 = QtWidgets.QLabel(self.centralwidget) 75 | self.label_8.setGeometry(QtCore.QRect(230, 170, 91, 16)) 76 | self.label_8.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 77 | "background-color: rgb(170, 255, 255);") 78 | self.label_8.setObjectName("label_8") 79 | self.label_9 = QtWidgets.QLabel(self.centralwidget) 80 | self.label_9.setGeometry(QtCore.QRect(400, 170, 71, 16)) 81 | self.label_9.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 82 | "background-color: rgb(170, 255, 255);") 83 | self.label_9.setObjectName("label_9") 84 | self.label_10 = QtWidgets.QLabel(self.centralwidget) 85 | self.label_10.setGeometry(QtCore.QRect(550, 170, 81, 16)) 86 | self.label_10.setStyleSheet("font: 75 9pt \"Adobe Gothic Std B\";\n" 87 | "background-color: rgb(170, 255, 255);") 88 | self.label_10.setObjectName("label_10") 89 | self.img2 = QtWidgets.QLabel(self.centralwidget) 90 | self.img2.setGeometry(QtCore.QRect(360, 30, 131, 121)) 91 | self.img2.setText("") 92 | self.img2.setObjectName("img2") 93 | self.img3 = QtWidgets.QLabel(self.centralwidget) 94 | self.img3.setGeometry(QtCore.QRect(520, 30, 131, 121)) 95 | self.img3.setText("") 96 | self.img3.setObjectName("img3") 97 | self.img4 = QtWidgets.QLabel(self.centralwidget) 98 | self.img4.setGeometry(QtCore.QRect(210, 190, 131, 121)) 99 | self.img4.setText("") 100 | self.img4.setObjectName("img4") 101 | self.img5 = QtWidgets.QLabel(self.centralwidget) 102 | self.img5.setGeometry(QtCore.QRect(360, 190, 131, 121)) 103 | self.img5.setText("") 104 | self.img5.setObjectName("img5") 105 | self.img6 = QtWidgets.QLabel(self.centralwidget) 106 | self.img6.setGeometry(QtCore.QRect(520, 190, 131, 121)) 107 | self.img6.setText("") 108 | self.img6.setObjectName("img6") 109 | self.img1 = QtWidgets.QLabel(self.centralwidget) 110 | self.img1.setGeometry(QtCore.QRect(210, 30, 131, 121)) 111 | self.img1.setText("") 112 | self.img1.setObjectName("img1") 113 | self.DCT = QtWidgets.QPushButton(self.centralwidget) 114 | self.DCT.setGeometry(QtCore.QRect(60, 200, 41, 21)) 115 | self.DCT.setObjectName("DCT") 116 | MainWindow.setCentralWidget(self.centralwidget) 117 | self.menubar = QtWidgets.QMenuBar(MainWindow) 118 | self.menubar.setGeometry(QtCore.QRect(0, 0, 686, 18)) 119 | self.menubar.setObjectName("menubar") 120 | MainWindow.setMenuBar(self.menubar) 121 | self.statusbar = QtWidgets.QStatusBar(MainWindow) 122 | self.statusbar.setObjectName("statusbar") 123 | MainWindow.setStatusBar(self.statusbar) 124 | 125 | self.retranslateUi(MainWindow) 126 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 127 | 128 | def retranslateUi(self, MainWindow): 129 | _translate = QtCore.QCoreApplication.translate 130 | MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) 131 | self.img_open.setText(_translate("MainWindow", "Browser")) 132 | self.label.setText(_translate("MainWindow", " Cover Image")) 133 | self.label_2.setText(_translate("MainWindow", "Input Message")) 134 | self.message_open.setText(_translate("MainWindow", "Browser")) 135 | self.label_3.setText(_translate("MainWindow", "Choose Attack Method")) 136 | self.comboBox.setItemText(0, _translate("MainWindow", "白噪声")) 137 | self.comboBox.setItemText(1, _translate("MainWindow", "旋转10°")) 138 | self.comboBox.setItemText(2, _translate("MainWindow", "旋转30°")) 139 | self.comboBox.setItemText(3, _translate("MainWindow", "椒盐噪声")) 140 | self.comboBox.setItemText(4, _translate("MainWindow", "小波压缩")) 141 | self.DWT.setText(_translate("MainWindow", "DWT")) 142 | self.label_4.setText(_translate("MainWindow", " Cover Image")) 143 | self.label_5.setText(_translate("MainWindow", "Input Message")) 144 | self.label_7.setText(_translate("MainWindow", "Watermarked Image")) 145 | self.label_8.setText(_translate("MainWindow", "Recovered Message")) 146 | self.label_9.setText(_translate("MainWindow", "Attacked Image")) 147 | self.label_10.setText(_translate("MainWindow", "Attacked Message")) 148 | self.DCT.setText(_translate("MainWindow", "DCT")) 149 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/mainUI.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | true 7 | 8 | 9 | 10 | 0 11 | 0 12 | 686 13 | 380 14 | 15 | 16 | 17 | MainWindow 18 | 19 | 20 | 21 | 22 | 23 | 10 24 | 30 25 | 111 26 | 21 27 | 28 | 29 | 30 | 31 | 32 | 33 | 130 34 | 30 35 | 41 36 | 21 37 | 38 | 39 | 40 | Browser 41 | 42 | 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 30 50 | 10 51 | 61 52 | 16 53 | 54 | 55 | 56 | font: 75 9pt "Adobe Gothic Std B"; 57 | background-color: rgb(170, 255, 255); 58 | 59 | 60 | Cover Image 61 | 62 | 63 | 64 | 65 | 66 | 30 67 | 70 68 | 61 69 | 16 70 | 71 | 72 | 73 | font: 75 9pt "Adobe Gothic Std B"; 74 | background-color: rgb(170, 255, 255); 75 | 76 | 77 | Input Message 78 | 79 | 80 | 81 | 82 | 83 | 10 84 | 90 85 | 111 86 | 21 87 | 88 | 89 | 90 | 91 | 92 | 93 | 130 94 | 90 95 | 41 96 | 21 97 | 98 | 99 | 100 | Browser 101 | 102 | 103 | 104 | 105 | 106 | 20 107 | 130 108 | 101 109 | 16 110 | 111 | 112 | 113 | font: 75 9pt "Adobe Gothic Std B"; 114 | background-color: rgb(170, 255, 255); 115 | 116 | 117 | Choose Attack Method 118 | 119 | 120 | 121 | 122 | 123 | 10 124 | 150 125 | 61 126 | 22 127 | 128 | 129 | 130 | 131 | 白噪声 132 | 133 | 134 | 135 | 136 | 旋转10° 137 | 138 | 139 | 140 | 141 | 旋转30° 142 | 143 | 144 | 145 | 146 | 椒盐噪声 147 | 148 | 149 | 150 | 151 | 小波压缩 152 | 153 | 154 | 155 | 156 | 157 | 158 | 10 159 | 200 160 | 41 161 | 21 162 | 163 | 164 | 165 | DWT 166 | 167 | 168 | 169 | 170 | 171 | 240 172 | 10 173 | 61 174 | 16 175 | 176 | 177 | 178 | font: 75 9pt "Adobe Gothic Std B"; 179 | background-color: rgb(170, 255, 255); 180 | 181 | 182 | Cover Image 183 | 184 | 185 | 186 | 187 | 188 | 400 189 | 10 190 | 61 191 | 16 192 | 193 | 194 | 195 | font: 75 9pt "Adobe Gothic Std B"; 196 | background-color: rgb(170, 255, 255); 197 | 198 | 199 | Input Message 200 | 201 | 202 | 203 | 204 | 205 | 540 206 | 10 207 | 91 208 | 16 209 | 210 | 211 | 212 | font: 75 9pt "Adobe Gothic Std B"; 213 | background-color: rgb(170, 255, 255); 214 | 215 | 216 | Watermarked Image 217 | 218 | 219 | 220 | 221 | 222 | 230 223 | 170 224 | 91 225 | 16 226 | 227 | 228 | 229 | font: 75 9pt "Adobe Gothic Std B"; 230 | background-color: rgb(170, 255, 255); 231 | 232 | 233 | Recovered Message 234 | 235 | 236 | 237 | 238 | 239 | 400 240 | 170 241 | 71 242 | 16 243 | 244 | 245 | 246 | font: 75 9pt "Adobe Gothic Std B"; 247 | background-color: rgb(170, 255, 255); 248 | 249 | 250 | Attacked Image 251 | 252 | 253 | 254 | 255 | 256 | 550 257 | 170 258 | 81 259 | 16 260 | 261 | 262 | 263 | font: 75 9pt "Adobe Gothic Std B"; 264 | background-color: rgb(170, 255, 255); 265 | 266 | 267 | Attacked Message 268 | 269 | 270 | 271 | 272 | 273 | 360 274 | 30 275 | 131 276 | 121 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 520 287 | 30 288 | 131 289 | 121 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 210 300 | 190 301 | 131 302 | 121 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 360 313 | 190 314 | 131 315 | 121 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 520 326 | 190 327 | 131 328 | 121 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 210 339 | 30 340 | 131 341 | 121 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 60 352 | 200 353 | 41 354 | 21 355 | 356 | 357 | 358 | DCT 359 | 360 | 361 | 362 | 363 | 364 | 365 | 0 366 | 0 367 | 686 368 | 18 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/nc.m: -------------------------------------------------------------------------------- 1 | function dNC = nc(ImageA,ImageB) 2 | 3 | ImageA=double(ImageA); 4 | ImageB=double(ImageB); 5 | M = size(ImageA,1); 6 | N = size(ImageA,2); 7 | d1=0 ; 8 | d2=0; 9 | d3=0; 10 | for i = 1:M 11 | for j = 1:N 12 | d1=d1+ImageA(i,j)*ImageB(i,j) ; 13 | d2=d2+ImageA(i,j)*ImageA(i,j) ; 14 | d3=d3+ImageB(i,j)*ImageB(i,j) ; 15 | end 16 | end 17 | dNC=d1/(sqrt(d2)*sqrt(d3)); 18 | return 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/picture/_copyright_small.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/picture/_copyright_small.bmp -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/picture/baboon.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/picture/baboon.ppm -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/picture/carrier_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/picture/carrier_image.jpg -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/picture/flag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lfreya/Digital-Watermark-use-python-and-matlab/aab6a91a8a9cad17b95d41e99ceed764b2533411/数字水印的嵌入与提取原型/picture/flag.jpg -------------------------------------------------------------------------------- /数字水印的嵌入与提取原型/ssim.m: -------------------------------------------------------------------------------- 1 | function [mssim, ssim_map] = ssim(cover_object, watermrkd_img, k, window, L) 2 | 3 | %======================================================================== 4 | %SSIM Index, Version 1.0 5 | %Copyright(c) 2003 Zhou Wang 6 | %All Rights Reserved. 7 | % 8 | %The author is with Howard Hughes Medical Institute, and Laboratory 9 | %for Computational Vision at Center for Neural Science and Courant 10 | %Institute of Mathematical Sciences, New York University. 11 | % 12 | %---------------------------------------------------------------------- 13 | %Permission to use, copy, or modify this software and its documentation 14 | %for educational and research purposes only and without fee is hereby 15 | %granted, provided that this copyright notice and the original authors' 16 | %names appear on all copies and supporting documentation. This program 17 | %shall not be used, rewritten, or adapted as the basis of a commercial 18 | %software or hardware product without first obtaining permission of the 19 | %authors. The authors make no representations about the suitability of 20 | %this software for any purpose. It is provided "as is" without express 21 | %or implied warranty. 22 | %---------------------------------------------------------------------- 23 | % 24 | %This is an implementation of the algorithm for calculating the 25 | %Structural SIMilarity (SSIM) index between two images. Please refer 26 | %to the following paper: 27 | % 28 | %Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image 29 | %quality assessment: From error visibility to structural similarity" 30 | %IEEE Transactios on Image Processing, vol. 13, no. 4, pp.600-612, 31 | %Apr. 2004. 32 | % 33 | %Kindly report any suggestions or corrections to zhouwang@ieee.org 34 | % 35 | %---------------------------------------------------------------------- 36 | % 37 | %Input : (1) img1: the first image being compared 38 | % (2) img2: the second image being compared 39 | % (3) K: constants in the SSIM index formula (see the above 40 | % reference). defualt value: K = [0.01 0.03] 41 | % (4) window: local window for statistics (see the above 42 | % reference). default widnow is Gaussian given by 43 | % window = fspecial('gaussian', 11, 1.5); 44 | % (5) L: dynamic range of the images. default: L = 255 45 | % 46 | %Output: (1) mssim: the mean SSIM index value between 2 images. 47 | % If one of the images being compared is regarded as 48 | % perfect quality, then mssim can be considered as the 49 | % quality measure of the other image. 50 | % If img1 = img2, then mssim = 1. 51 | % (2) ssim_map: the SSIM index map of the test image. The map 52 | % has a smaller size than the input images. The actual size: 53 | % size(img1) - size(window) + 1. 54 | % 55 | %Default Usage: 56 | % Given 2 test images img1 and img2, whose dynamic range is 0-255 57 | % 58 | % [mssim ssim_map] = ssim_index(img1, img2); 59 | % 60 | %Advanced Usage: 61 | % User defined parameters. For example 62 | % 63 | % K = [0.05 0.05]; 64 | % window = ones(8); 65 | % L = 100; 66 | % [mssim ssim_map] = ssim_index(img1, img2, K, window, L); 67 | % 68 | %See the results: 69 | % 70 | % mssim %Gives the mssim value 71 | % imshow(max(0, ssim_map).^4) %Shows the SSIM index map 72 | % 73 | %======================================================================== 74 | 75 | if (nargin < 2 | nargin > 5) 76 | ssim_index = -Inf; 77 | ssim_map = -Inf; 78 | return; 79 | end 80 | if (size(cover_object) ~= size(watermrkd_img)) 81 | ssim_index = -Inf; 82 | ssim_map = -Inf; 83 | return; 84 | end 85 | [M N] = size(cover_object); 86 | if (nargin == 2) 87 | if ((M < 11) | (N < 11)) 88 | ssim_index = -Inf; 89 | ssim_map = -Inf; 90 | return 91 | end 92 | window = fspecial('gaussian', 11, 1.5); % 93 | k(1) = 0.01; % default settings 94 | k(2) = 0.03; % 95 | L = 255; % 96 | end 97 | if (nargin == 3) 98 | if ((M < 11) | (N < 11)) 99 | ssim_index = -Inf; 100 | ssim_map = -Inf; 101 | return 102 | end 103 | window = fspecial('gaussian', 11, 1.5); 104 | L = 255; 105 | if (length(k) == 2) 106 | if (k(1) < 0 | k(2) < 0) 107 | ssim_index = -Inf; 108 | ssim_map = -Inf; 109 | return; 110 | end 111 | else 112 | ssim_index = -Inf; 113 | ssim_map = -Inf; 114 | return; 115 | end 116 | end 117 | if (nargin == 4) 118 | [H W] = size(window); 119 | if ((H*W) < 4 | (H > M) | (W > N)) 120 | ssim_index = -Inf; 121 | ssim_map = -Inf; 122 | return 123 | end 124 | L = 255; 125 | if (length(k) == 2) 126 | if (k(1) < 0 | k(2) < 0) 127 | ssim_index = -Inf; 128 | ssim_map = -Inf; 129 | return; 130 | end 131 | else 132 | ssim_index = -Inf; 133 | ssim_map = -Inf; 134 | return; 135 | end 136 | end 137 | if (nargin == 5) 138 | [H W] = size(window); 139 | if ((H*W) < 4 | (H > M) | (W > N)) 140 | ssim_index = -Inf; 141 | ssim_map = -Inf; 142 | return 143 | end 144 | if (length(k) == 2) 145 | if (k(1) < 0 | k(2) < 0) 146 | ssim_index = -Inf; 147 | ssim_map = -Inf; 148 | return; 149 | end 150 | else 151 | ssim_index = -Inf; 152 | ssim_map = -Inf; 153 | return; 154 | end 155 | end 156 | C1 = (k(1)*L)^2; 157 | C2 = (k(2)*L)^2; 158 | window = window/sum(sum(window)); 159 | 160 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 161 | % RGB to Gray 162 | if size(cover_object,3)~=1 % not gray 163 | org=rgb2gray(cover_object); 164 | test=rgb2gray(watermrkd_img); 165 | Y1=org; 166 | Y2=test; 167 | cover_object=double(Y1); % uint8 to double 168 | watermrkd_img=double(Y2); 169 | else % is gray 170 | cover_object=double(cover_object); 171 | watermrkd_img=double(watermrkd_img); 172 | end 173 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 174 | 175 | cover_object = double(cover_object); 176 | watermrkd_img = double(watermrkd_img); 177 | mu1 = filter2(window, cover_object, 'valid'); 178 | mu2 = filter2(window, watermrkd_img, 'valid'); 179 | mu1_sq = mu1.*mu1; 180 | mu2_sq = mu2.*mu2; 181 | mu1_mu2 = mu1.*mu2; 182 | sigma1_sq = filter2(window, cover_object.*cover_object, 'valid') - mu1_sq; 183 | sigma2_sq = filter2(window, watermrkd_img.*watermrkd_img, 'valid') - mu2_sq; 184 | sigma12 = filter2(window, cover_object.*watermrkd_img, 'valid') - mu1_mu2; 185 | 186 | if (C1 > 0 & C2 > 0) 187 | ssim_map = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))./((mu1_sq + mu2_sq + C1).*(sigma1_sq + sigma2_sq + C2)); 188 | else 189 | numerator1 = 2*mu1_mu2 + C1; 190 | numerator2 = 2*sigma12 + C2; 191 | denominator1 = mu1_sq + mu2_sq + C1; 192 | denominator2 = sigma1_sq + sigma2_sq + C2; 193 | ssim_map = ones(size(mu1)); 194 | index = (denominator1.*denominator2 > 0); 195 | ssim_map(index) = (numerator1(index).*numerator2(index))./(denominator1(index).*denominator2(index)); 196 | index = (denominator1 ~= 0) & (denominator2 == 0); 197 | ssim_map(index) = numerator1(index)./denominator1(index); 198 | end 199 | 200 | mssim = mean2(ssim_map); 201 | return --------------------------------------------------------------------------------