当前位置:   article > 正文

论文复现代码Reversible Watermarking Algorithm Using Sorting and Prediction_复现代码英语

复现代码英语

论文简述

见我文章

论文简述附复现代码Reversible Watermarking Algorithm Using Sorting and Prediction比较经典的PEE算法_zrc007007的博客-CSDN博客

复现代码

注:

代码不可商用!

代码不可商用!

代码不可商用!

  1. from skimage import io
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. class Test:
  5. def __init__(self):
  6. self.data = np.array(
  7. [[251, 252, 253, 253],
  8. [252, 254, 252, 251],
  9. [252, 252, 252, 252],
  10. [252, 253, 252, 255]]
  11. )
  12. def int2bin(x, length):
  13. string = ''
  14. while x != 0:
  15. string = str(x % 2) + string
  16. x = x // 2
  17. if len(string) > length:
  18. raise Exception("The length of x is longer actually!")
  19. elif len(string) < length:
  20. return '0' * (length - len(string)) + string
  21. else:
  22. return string
  23. def countMiu(x1, x2, x3, x4):
  24. delta = []
  25. miu = 0
  26. x1 = float(x1)
  27. x2 = float(x2)
  28. x3 = float(x3)
  29. x4 = float(x4)
  30. if x4 != -1:
  31. delta.append(abs(x1 - x2))
  32. delta.append(abs(x2 - x3))
  33. delta.append(abs(x3 - x4))
  34. delta.append(abs(x4 - x1))
  35. deltaAvg = (delta[0] + delta[1] + delta[2] + delta[3]) / 4
  36. for i in range(4):
  37. miu += (delta[i] - deltaAvg) ** 2
  38. return miu / 4
  39. elif x3 != -1:
  40. delta.append(abs(x1 - x2))
  41. delta.append(abs(x2 - x3))
  42. delta.append(abs(x3 - x1))
  43. deltaAvg = (delta[0] + delta[1] + delta[2]) / 3
  44. for i in range(3):
  45. miu += (delta[i] - deltaAvg) ** 2
  46. return miu / 3
  47. else:
  48. return 10 ** 5
  49. def countPrdMiu(img, row, column):
  50. if row == 0 and column == 0:
  51. prd = (int(img[0][1]) + int(img[1][0])) // 2
  52. miu = countMiu(int(img[0][1]), int(img[1][0]), -1, -1)
  53. elif row == (img.shape[0] - 1) and column == (img.shape[1] - 1):
  54. prd = (int(img[img.shape[0] - 2][img.shape[0] - 1]) + int(img[img.shape[0] - 1][img.shape[1] - 2])) // 2
  55. miu = countMiu(int(img[img.shape[0] - 2][img.shape[0] - 1]), int(img[img.shape[0] - 1][img.shape[1] - 2]), -1,
  56. -1)
  57. elif row == 0:
  58. prd = (int(img[0][column - 1]) + int(img[0][column + 1]) + int(img[1][column])) // 3
  59. miu = countMiu(int(img[0][column - 1]), int(img[0][column + 1]), int(img[1][column]), -1)
  60. elif row == img.shape[0] - 1:
  61. prd = (int(img[row][column - 1]) + int(img[row][column + 1]) + int(img[row - 1][column])) // 3
  62. miu = countMiu(int(img[row][column - 1]), int(img[row][column + 1]), int(img[row - 1][column]), -1)
  63. elif column == 0:
  64. prd = (int(img[row - 1][0]) + int(img[row + 1][0]) + int(img[row][1])) // 3
  65. miu = countMiu(int(img[row - 1][0]), int(img[row + 1][0]), int(img[row][1]), -1)
  66. elif column == img.shape[1] - 1:
  67. prd = (int(img[row - 1][column]) + int(img[row + 1][column]) + int(img[row][column - 1])) // 3
  68. miu = countMiu(int(img[row - 1][column]), int(img[row + 1][column]), int(img[row][column - 1]), -1)
  69. else:
  70. prd = (int(img[row - 1][column]) + int(img[row + 1][column])
  71. + int(img[row][column - 1]) + int(img[row][column + 1])) // 4
  72. miu = countMiu(int(img[row - 1][column]), int(img[row + 1][column]),
  73. int(img[row][column - 1]), int(img[row][column + 1]))
  74. return prd, miu
  75. def HistogramShift(origin, prd, Tn, Tp, b):
  76. d = origin - prd
  77. if Tn <= d <= Tp:
  78. D = 2 * d + b
  79. elif d > Tp:
  80. D = d + Tp + 1
  81. else:
  82. D = d + Tn
  83. return D
  84. def judgeTwiceFlow(origin, prd, Tn, Tp):
  85. if origin < prd:
  86. origin2 = prd + HistogramShift(origin, prd, Tn, Tp, 0)
  87. if origin2 < 0:
  88. return 1
  89. else:
  90. if prd + HistogramShift(origin2, prd, Tn, Tp, 0) < 0:
  91. return 0
  92. else:
  93. return -1
  94. else:
  95. origin2 = prd + HistogramShift(origin, prd, Tn, Tp, 1)
  96. if origin2 > 255:
  97. return 1
  98. else:
  99. if prd + HistogramShift(origin2, prd, Tn, Tp, 1) > 255:
  100. return 0
  101. else:
  102. return -1
  103. def embed(img, row, column, origin, prd, Tn, Tp, b):
  104. img[row][column] = prd + HistogramShift(origin, prd, Tn, Tp, b)
  105. def countPosition(img, place):
  106. row = place // img.shape[1]
  107. if img.shape[1] % 2 == 1:
  108. column = place % img.shape[1]
  109. elif row % 2 == 0:
  110. column = place % img.shape[1]
  111. else:
  112. column = place % img.shape[1] + 1
  113. return row, column
  114. def embedOnePattern(place, Tn, Tp, P, processed):
  115. encrypted = processed
  116. Slsb = ''
  117. head = int2bin(-Tn, 7) + int2bin(Tp, 7) + int2bin(len(P), 20)
  118. row_dic = []
  119. row_dic_list = []
  120. row_dic_list_sorted = []
  121. for z in range(encrypted.shape[0]):
  122. row_dic.append({})
  123. row_dic_list.append(z)
  124. row_dic_list_sorted.append(z)
  125. start = 1
  126. locationMap = ''
  127. needDot = True
  128. while place < img.shape[0] * img.shape[1]:
  129. row, column = countPosition(img, place)
  130. if (place + 2) // img.shape[1] == row:
  131. prd, miu = countPrdMiu(img, row, column)
  132. origin = img[row][column]
  133. row_dic[row][row, column, origin, prd] = miu
  134. else:
  135. prd, miu = countPrdMiu(img, row, column)
  136. origin = img[row][column]
  137. row_dic[row][row, column, origin, prd] = miu
  138. row_dic_list[row] = list(zip(row_dic[row].values(), row_dic[row].keys()))
  139. row_dic_list_sorted[row] = sorted(row_dic_list[row])
  140. # 没有放在外面是因为接着判断为换行,在处理这个行尾的时候,用这个固定的row,直接sorting完这一行
  141. for i in range(len(row_dic_list_sorted[row])):
  142. # 标记出位图
  143. if start == 1 and judgeTwiceFlow(row_dic_list_sorted[row][i][1][2],
  144. row_dic_list_sorted[row][i][1][3], Tn, Tp) >= 0:
  145. continue
  146. else:
  147. start = 0
  148. if judgeTwiceFlow(row_dic_list_sorted[row][i][1][2],
  149. row_dic_list_sorted[row][i][1][3], Tn, Tp) != -1:
  150. locationMap += str(judgeTwiceFlow(row_dic_list_sorted[row][i][1][2],
  151. row_dic_list_sorted[row][i][1][3], Tn, Tp))
  152. place += 2
  153. start = 1
  154. embedded_message = locationMap
  155. # 利用之前算出来的sorting顺序,直接进行嵌入embed
  156. for x in range(img.shape[0]):
  157. for y in range(len(row_dic_list_sorted[x])):
  158. if x * img.shape[1] + y < 34:
  159. encrypted[row_dic_list_sorted[x][y][1][0]][row_dic_list_sorted[x][y][1][1]] = \
  160. img[row_dic_list_sorted[x][y][1][0]][row_dic_list_sorted[x][y][1][1]] // 2 * 2 + int(head[0])
  161. Slsb += str(img[row_dic_list_sorted[x][y][1][0]][row_dic_list_sorted[x][y][1][1]] % 2)
  162. head = head[1:]
  163. else:
  164. if start == 1:
  165. embedded_message = locationMap + Slsb + P
  166. start = 0
  167. d = row_dic_list_sorted[x][y][1][2] - row_dic_list_sorted[x][y][1][3]
  168. if Tn <= d <= Tp and len(embedded_message) > 0:
  169. embed(encrypted, row_dic_list_sorted[x][y][1][0], row_dic_list_sorted[x][y][1][1],
  170. row_dic_list_sorted[x][y][1][2], row_dic_list_sorted[x][y][1][3], Tn, Tp,
  171. int(embedded_message[0]))
  172. embedded_message = embedded_message[1:]
  173. else:
  174. embed(encrypted, row_dic_list_sorted[x][y][1][0], row_dic_list_sorted[x][y][1][1],
  175. row_dic_list_sorted[x][y][1][2], row_dic_list_sorted[x][y][1][3], Tn, Tp,
  176. 0) # 超过界限就嵌入0
  177. if len(embedded_message) > len(P):
  178. raise Exception("Didn't finish embedding lacation map and Slsb!")
  179. if len(embedded_message) == 0:
  180. print("No need to embed Dot set!")
  181. needDot = False
  182. return encrypted, embedded_message, needDot
  183. def encode(img, Tn, Tp, P):
  184. '''
  185. Encode the original imagine.
  186. :param img: original imagine
  187. :param Tn: start threshold
  188. :param Tp: end threshold
  189. :param P: payload
  190. :return: The encrypted imagine and the bool value sign whether need Dot pattern encoding.
  191. '''
  192. if img.shape[0] * img.shape[1] < 34 * 4:
  193. raise Exception("The imagine is too small!")
  194. if Tn >= 0:
  195. raise Exception("Tn need to be negative!")
  196. if Tp < 0:
  197. raise Exception("Tp need to be positive!")
  198. encrypted = np.array(img)
  199. encrypted, embedded_message, needDot = embedOnePattern(0, Tn, Tp, P, encrypted)
  200. if needDot is True:
  201. encrypted, embedded_message, needDot = embedOnePattern(1, Tn, Tp, P, encrypted)
  202. if len(embedded_message) > 0:
  203. raise Exception("Length of P,", len(P), ", is much more than this picture can be embedded!")
  204. else:
  205. return encrypted, True
  206. else:
  207. return encrypted, False
  208. def Slsb2int(string):
  209. if len(string) != 34:
  210. raise Exception("Given string's length isn't 34!")
  211. T = [0, 0]
  212. P = 0
  213. cut = [string[0:7], string[7:14], string[14: 34]]
  214. for i in range(2):
  215. for j in range(7):
  216. T[i] += int(cut[i][-1]) * 2 ** j
  217. cut[i] = cut[i][0:-1]
  218. for j in range(20):
  219. P += int(cut[2][-1]) * 2 ** j
  220. cut[2] = cut[2][0:-1]
  221. return T[0], T[1], P
  222. def countPattenNum(isOdd, place, img):
  223. if isOdd is False:
  224. return img.shape[0] * img.shape[1] // 2
  225. if isOdd is True:
  226. if place == 0:
  227. return img.shape[0] * img.shape[1] // 2 + 1
  228. else:
  229. return img.shape[0] * img.shape[1] // 2
  230. def judgeOnceFlow(origin, prd, Tn, Tp):
  231. if origin < prd:
  232. if prd + HistogramShift(origin, prd, Tn, Tp, 0) < 0:
  233. return True
  234. else:
  235. return False
  236. else:
  237. if prd + HistogramShift(origin, prd, Tn, Tp, 1) > 255:
  238. return True
  239. else:
  240. return False
  241. def extractPixel(origin, prd):
  242. result = (origin - prd) % 2
  243. return result
  244. def decodeShift(origin, prd, Tn, Tp):
  245. D = origin - prd
  246. if 2 * Tn <= D <= 2 * Tp + 1:
  247. d = D // 2
  248. elif D > 2 * Tp + 1:
  249. d = D - Tp - 1
  250. else:
  251. d = D - Tn
  252. return d
  253. def restoreImg(needResumed, message, bitNum, row_dic_list_sorted, Tn, Tp):
  254. processed = needResumed
  255. start = 1
  256. bitPosition = 0
  257. Slsb = message[bitNum:bitNum + 34]
  258. for i in range(processed.shape[0]):
  259. for j in range(len(row_dic_list_sorted[i])):
  260. if i * processed.shape[0] + j < 34:
  261. processed[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] = \
  262. processed[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] - \
  263. processed[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] % 2 + int(Slsb[0])
  264. Slsb = Slsb[1:]
  265. else:
  266. if start == 1 and judgeOnceFlow(row_dic_list_sorted[i][j][1][2],
  267. row_dic_list_sorted[i][j][1][3], Tn, Tp) is True:
  268. continue
  269. else:
  270. start = 0
  271. if judgeOnceFlow(row_dic_list_sorted[i][j][1][2],
  272. row_dic_list_sorted[i][j][1][3], Tn, Tp) is False:
  273. processed[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] \
  274. = row_dic_list_sorted[i][j][1][3] \
  275. + decodeShift(row_dic_list_sorted[i][j][1][2], row_dic_list_sorted[i][j][1][3], Tn, Tp)
  276. else:
  277. if message[bitPosition] == 0:
  278. processed[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] \
  279. = row_dic_list_sorted[i][j][1][3] \
  280. + decodeShift(row_dic_list_sorted[i][j][1][2], row_dic_list_sorted[i][j][1][3], Tn, Tp)
  281. else:
  282. pass
  283. bitPosition += 1
  284. return processed
  285. def decodeOnePattern(place, encrypted):
  286. resumed = encrypted
  287. odd = False
  288. if encrypted.shape[0] % 2 != 0 and encrypted.shape[1] % 2 != 0:
  289. odd = True
  290. head = ''
  291. start = 1
  292. startRow = 0
  293. message = ''
  294. bitPosition = 0
  295. row_dic = []
  296. row_dic_list = []
  297. row_dic_list_sorted = []
  298. for z in range(encrypted.shape[0]):
  299. row_dic.append({})
  300. row_dic_list.append(z)
  301. row_dic_list_sorted.append(z)
  302. for i in range(countPattenNum(odd, place, encrypted)):
  303. row, column = countPosition(encrypted, place)
  304. if (place + 2) // encrypted.shape[1] == row:
  305. prd, miu = countPrdMiu(encrypted, row, column)
  306. modified = encrypted[row][column]
  307. row_dic[row][row, column, modified, prd] = miu
  308. else:
  309. prd, miu = countPrdMiu(encrypted, row, column)
  310. modified = encrypted[row][column]
  311. row_dic[row][row, column, modified, prd] = miu
  312. row_dic_list[row] = list(zip(row_dic[row].values(), row_dic[row].keys()))
  313. row_dic_list_sorted[row] = sorted(row_dic_list[row])
  314. place += 2
  315. place = 0
  316. needBreak = False
  317. for i in range(encrypted.shape[0]):
  318. for j in range(len(row_dic_list_sorted[i])):
  319. if i * encrypted.shape[1] + j >= 34:
  320. needBreak = True
  321. if needBreak is True:
  322. break
  323. head += str(encrypted[row_dic_list_sorted[i][j][1][0]][row_dic_list_sorted[i][j][1][1]] % 2)
  324. if needBreak is True:
  325. break
  326. Tn, Tp, P = Slsb2int(head)
  327. Tn = -Tn
  328. if Tn >= 0:
  329. raise Exception("The extracted Tn isn't negative!")
  330. if Tp < 0:
  331. raise Exception("The extracted Tp isn't positive!")
  332. for i in range(encrypted.shape[0]):
  333. for j in range(len(row_dic_list_sorted[i])):
  334. if i * encrypted.shape[1] + j < 34:
  335. pass
  336. else:
  337. if start == 1 and judgeOnceFlow(row_dic_list_sorted[i][j][1][2],
  338. row_dic_list_sorted[i][j][1][3], Tn, Tp) is True:
  339. continue
  340. else:
  341. start = 0
  342. if judgeOnceFlow(row_dic_list_sorted[i][j][1][2],
  343. row_dic_list_sorted[i][j][1][3], Tn, Tp) is False:
  344. D = row_dic_list_sorted[i][j][1][2] - row_dic_list_sorted[i][j][1][3]
  345. if 2 * Tn <= D <= 2 * Tp + 1:
  346. message += str(extractPixel(row_dic_list_sorted[i][j][1][2],
  347. row_dic_list_sorted[i][j][1][3]))
  348. else:
  349. if message[bitPosition] == 0:
  350. D = row_dic_list_sorted[i][j][1][2] - row_dic_list_sorted[i][j][1][3]
  351. if 2 * Tn <= D <= 2 * Tp + 1:
  352. message += str(extractPixel(row_dic_list_sorted[i][j][1][2],
  353. row_dic_list_sorted[i][j][1][3]))
  354. bitPosition += 1
  355. elif message[bitPosition] == 1:
  356. bitPosition += 1
  357. resumed = restoreImg(resumed, message, bitPosition, row_dic_list_sorted, Tn, Tp)
  358. info = message[bitPosition + 34:bitPosition + 34 + P]
  359. return resumed, info
  360. # 还有第二次嵌入要处理一下,到时候写
  361. def decode(encrypted, needDot):
  362. '''
  363. Decode the encrypted imagine.
  364. :param encrypted: the encrypted imagine
  365. :param needDot: whether you need decoding Dot set or not
  366. :return: The original imagine and the secret information.
  367. '''
  368. if img.shape[0] * img.shape[1] < 34 * 4:
  369. raise Exception("The imagine is too small!")
  370. if needDot is False:
  371. imagine, info = decodeOnePattern(0, encrypted)
  372. else:
  373. encrypted1, info1 = decodeOnePattern(1, encrypted)
  374. imagine, info2 = decodeOnePattern(0, encrypted1)
  375. info = info1 + info2
  376. return imagine, info
  377. if __name__ == "__main__":
  378. img = io.imread("../img/lena_gray_512.tif") # 在这里放你要处理的图像 place your imagine here
  379. # img = Test().data
  380. # print(img)
  381. encrypted, needDot = encode(img, -1, 0, '100000')
  382. print("need Dot:", needDot)
  383. resumedImg, info = decode(encrypted, needDot)
  384. print("The secret info is:", info)
  385. print("img == resumedImg:")
  386. print(img == resumedImg)
  387. plt.set_cmap(cmap="gray")
  388. plt.subplot(131)
  389. plt.imshow(img)
  390. plt.title("Original imagery")
  391. plt.subplot(132)
  392. plt.imshow(encrypted)
  393. plt.title("Encrypted imagery")
  394. plt.subplot(133)
  395. plt.imshow(resumedImg)
  396. plt.title("Resumed imagery")
  397. plt.show()

结果如下:

代码只写了处理嵌入Cross集的,如果嵌入信息超过Cross集容量上限而要用到Dot集嵌入的我还没写完,看以后有机会补充没有。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/807766
推荐阅读
  

闽ICP备14008679号