![](/img/trans.png)
[英]Change pixel RGB values individually according to a threshold in Python
[英]Looping over the threshold area does not change pixel values
我目前正在設計一種隱寫術系統,該系統使用 Python 和 OpenCV 庫使用多種技術(K-means、Canny 邊緣檢測)檢測圖像中的某個區域。 我在更新圖像像素值以在最低有效位中包含我的秘密數據時面臨一個巨大的問題。
經過幾次計算,我開始找到閾值。
thresh = cv.adaptiveThreshold(imgray,100,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV,11,2)
為了測試該區域,我執行了以下操作:
Testim=np.copy(originalImage)
Testim[thresh==0]=[0,255,0]
plt.imshow(Testim)
plt.show()
它顯示了這張圖片,它指示了我想要循環的區域:
在那之后,我經歷了一個循環,我將向您展示它的一個片段,它遍歷 RGB 值並用秘密數據中的一點來更改每個最低有效位。 我要注意的是原始圖像形狀是(1024,1024,3),圖像[thresh==0]的形狀是(863843, 3):
for i in range(image[thresh==0].shape[0]):
# convert RGB values to binary format
r, g, b = to_bin(image[thresh==0][i])
# modify the least significant bit only if there is still data to store
if data_index < data_len:
# least significant red pixel bit
image[thresh==0][i][0] =int (r[:-1] + binary_secret_data[data_index], 2)
data_index += 1
if data_index < data_len:
# least significant green pixel bit
image[thresh==0][i][1] = int (g[:-1] + binary_secret_data[data_index], 2)
data_index += 1
if data_index < data_len:
# least significant blue pixel bit
image[thresh==0][i][2] = int (b[:-1] + binary_secret_data[data_index], 2)
data_index += 1
# if data is encoded, just break out of the loop
if data_index >= data_len:
plt.imshow(image)
break
return image,thresh
問題是 RGB 的值在循環內外根本沒有變化,我添加了一些打印語句,它一直顯示為零,我還嘗試顯式分配 1,但它也不起作用。
我想指出,這只是編碼 function 的一部分
我會很感激你的幫助
您的問題是高級索引返回 arrays 的副本,因此通過執行image[thresh==0][i][j]
一直修改新創建的副本,然后將其丟棄。
讓我們從一些假數據開始
import cv2
import numpy as np
np.random.seed(0)
original = np.random.randint(0, 255, (1024, 1024, 3)).astype(np.uint8)
gray = cv2.cvtColor(original, cv2.COLOR_RGB2GRAY)
thresh = cv2.adaptiveThreshold(gray, 100, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
copy = np.copy(original)
copy[thresh==0] = [0, 255, 0]
現在看看會發生什么
>>> copy[thresh==0][0]
array([ 0, 255, 0], dtype=uint8)
>>> copy[thresh==0][0] = [1, 2, 3]
>>> copy[thresh==0][0]
array([ 0, 255, 0], dtype=uint8)
為了使結果保持不變,您應該使用numpy.where
來獲取閾值為 0 的各個索引。
idx = np.where(thresh==0)
for row, col in zip(*idx):
r, g, b = to_bin(copy[row,col])
copy[row,col,0] = modified_red_pixel
# etc
我個人建議如下,這樣您就可以避免 python 循環並不斷檢查您是否還有要嵌入的數據。
binary_secret_data = '01010000101010010101010001001100'
binary_secret_data = np.array(list(map(int, binary_secret_data)))
secret_len = len(binary_secret_data)
# The result is a tuple of (array of all row coords, array of all column coords)
idx = np.where(thresh==0)
# Make 3 copies of each pixel coordinate and add 0, 1, 2 repeatedly for the RGB of each pixel
idx = (np.repeat(idx[0], 3), np.repeat(idx[1], 3), np.array([0, 1, 2] * len(idx[0])))
# Only keep as many pixels as data you have to embed
idx = (idx[0][:secret_len], idx[1][:secret_len], idx[2][:secret_len])
# Boom, power of vectorisation
copy[idx] = copy[idx] & 0xfe | binary_secret_data
現在您可以看到前32個像素已成功修改
>>> copy[thresh==0][:15]
array([[ 0, 255, 0],
[ 1, 254, 0],
[ 0, 254, 1],
[ 0, 255, 0],
[ 1, 254, 0],
[ 1, 254, 1],
[ 0, 255, 0],
[ 1, 254, 0],
[ 0, 255, 0],
[ 0, 255, 1],
[ 0, 254, 0],
[ 0, 255, 0],
[ 0, 255, 0],
[ 0, 255, 0],
[ 0, 255, 0]], dtype=uint8)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.