├── 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 |
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
--------------------------------------------------------------------------------