close

opencv 隱藏浮水印

本文章舉例的是灰階的圖片。我們先來講解圖片的LSB與MSB。灰階的圖片的像素值是0~255。
一張圖片是由很多的0~255的數值所組成。就是所謂的像素。
8個 bit,可以表示值的範圍為 0~255。
因此,比方說 226的二進制就是 11100010。
其中,越靠近左邊的越重要。也就是所謂的MSB。然後靠近右邊的相對來說較為不重要,就是所謂的LSB。
像是二進制中 1000000 轉換成十進制是等於128。相當於255的一半。

當我們要做隱藏浮水印時,就可以將MSB轉換成LSB在加入另一張圖片中。
例如:


今天有個照片的其中一個像素是 11011011 ,而我們要在這個的照片中加入一個隱藏的圖片。
那我們可以將 11011011 的LSB去除。變成 11011010。
假如我們要加入的圖片是 11001011 我們可以將他的MSB保留,其他的bit去除。
變成 10000000 然後在右邊位移7個bit。變成 00000001。
然後再將兩個像素值相加。 11011010 + 00000001 = 11011011。


我們這邊以圖片來舉例。
下圖是原始圖片。


這是我們要加入的浮水印。


這是我們加入浮水印的結果。可以發現是完全看不出來有浮水印的。


當我們要顯示浮水印時。只需要將上面所舉的例子。
只要將 11011011 的數值,往左邊移7格。就會變成 1000000 。

我們就可以看到浮水印出現在圖片中了。


下方為完整的程式碼:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main()
{
	Mat src = imread("test1.png", 0);
	Mat qrcode = imread("test_qrcode.png", 0);
 
	for (int i = 0; i < qrcode.rows; i++) {
		for (int j = 0; j < qrcode.cols; j++) {
			src.at<uchar>(i, j) = (int)(src.at<uchar>(i, j) & 0b11111110) + \
				((int)(qrcode.at<uchar>(i, j) & 0b10000000) >> 7);
		}
	}

	imwrite("result_qrcode.png", src);

	Mat result_qrcode = imread("result_qrcode.png", 0);

	for (int i = 0; i < result_qrcode.rows; i++) {
		for (int j = 0; j < result_qrcode.cols; j++) {
			if ((result_qrcode.at<uchar>(i, j) & 0b00000001)) {
				result_qrcode.at<uchar>(i, j) = 255;
			}
			else {
				result_qrcode.at<uchar>(i, j) = 0;
			}
		}
	}


	imshow("src", src);
	imshow("qrcode", qrcode);
	imshow("result_qrcode", result_qrcode);
	waitKey();
}

如需更多客製化服務:


另外有安裝或者其他使用上的問題,皆可參考下列篇章:

如有任何問題歡迎下方留言討論!!!

arrow
arrow

    微笑創客 發表在 痞客邦 留言(0) 人氣()