Я пытаюсь создать класс Java для реализации стеганографии LSB-изображений.
Для этого я использую OpenCV 3.2.
Я написал логику кодирования в методе encodeImage(String message)
класса LSBImageStego
, который будет принимать секретное сообщение и кодировать его в заданном изображении обложки (изображение обложки будет взято конструктором).
Я могу изменять значения пикселей путем изменения битов LSB(Я изменяю биты LSB только одного канала). Я использую MatObj.put(row,col,data)
для записи новых значений пикселей. Я пытался напечатать эти новые значения пикселей после put()
, и значения пикселей были успешно изменены.
Я возвращаю CoverImage (поскольку я внес изменения путем кодирования сообщения) и сохраняю изображение с помощью imwrite()
.
Теперь, когда я пытаюсь декодировать EncodedImage, я обнаружил, чтоИзображение имело значения старого пикселя, но не значения кодированного пикселя. Это указывает на то, что, хотя я написал значения кодированного пикселя, используя put()
в encodeImage(String message)
, объект Mat
не возвращался.
Здесьтрескаe для encodeImage(String message)
класса LSBImageStego
/**
getBeautifiedBinaryString()
Returns a binary string of length 8 by taking a number.
This function is working perfectly.
*/
/**
binaryStringMessage
is a private String in the class & contains the Binary form of the Secret Message.
*/
/**
This function takes Secret Message and replaces 2 bits from LSB(First Channel of Image)
with the bits of Message
*/
public Mat encodeImage(String message){
/**
//coverImage is a Mat Object & following is the code in constructor of a class
this.coverImage = coverImage;
this.coverImage_rows = (int)coverImage.size().height;
this.coverImage_cols = (int)coverImage.size().width;
*/
System.out.println("Number of Rows : " + this.coverImage_rows);
System.out.println("Number of Columns : " + this.coverImage_cols);
// This is used as a pointer in the BinaryString ,so that,it can be embedded easily
int messageStringCounter = 0;
for(int rowCount = 0 ; rowCount <= this.coverImage_rows -1 ; rowCount++){
for(int colCount = 0; colCount <= this.coverImage_cols -1 ; colCount++){
try{
if(messageStringCounter > this.binaryStringMessage.length() - 2 ){
System.out.println("RETURNING pic");
return this.coverImage;
}
String newLSBBits = this.binaryStringMessage.substring(messageStringCounter , messageStringCounter+2);
System.out.println(">> "+messageStringCounter + " >> " + newLSBBits);
messageStringCounter+=2;
System.out.println("ORIGINAL : "+this.getBeautifiedBinaryString(this.coverImage.get(rowCount , colCount)[0]));
String modifiedBinaryString = this.getBeautifiedBinaryString(this.coverImage.get(rowCount , colCount)[0]).substring(0 , this.getBeautifiedBinaryString(this.coverImage.get(rowCount , colCount)[0]).length() - 2) + newLSBBits;
System.out.println("MODIFIED : " + modifiedBinaryString);
double[] data = new double[3];
data[0] = Integer.parseInt(modifiedBinaryString , 2);
data[1] = this.coverImage.get(rowCount , colCount)[1];
data[2] = this.coverImage.get(rowCount , colCount)[2];
// Im checking whether the Pixel values are being changed as expected or not.
System.out.println("BEFORE : " + this.coverImage.get(rowCount , colCount)[0]);
this.coverImage.put(rowCount , colCount , data);
System.out.println("AFTER : " + this.coverImage.get(rowCount , colCount)[0]);
// The Pixel values were changed as expected
}catch(Exception e){
System.out.println("Exception Handled");
}
}
}
return this.coverImage;
}
, и я вызываю вышеуказанный метод из main()
в другом классе следующим образом.
public class Imple {
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args){
Imgcodecs imageCodecs = new Imgcodecs();
Mat mat = imageCodecs.imread("C:\\Users\\XYZ\\Desktop\\test.jpg");
LSBImageStego obj = new LSBImageStego(mat);
String message = "Hello World";
if(obj.checkEncodePossibility(message)){
System.out.println("OK");
}else{
System.out.println("NO");
}
Mat encodedImage = obj.encodeImage(message).clone();
imageCodecs.imwrite("C:\\Users\\XYZ\\Desktop\\test_ENCODED.jpg" ,encodedImage );
Mat mat2 = imageCodecs.imread("C:\\Users\\XYZ\\Desktop\\test_ENCODED.jpg");
// While debugging the Below function,I found that the Changed Pixel values were not being written back to the Disk
obj.decodeImage(mat2);
// In the above method,as part of debugging,I'm printing the Pixel values to the console.
}
}
Я позаботилсядругих логик, таких как длина двоичной строки сообщения нечетная или четная и т. д. ...
Единственная проблема заключается в том, что EncodedImage, который я сохраняю на диск, не содержит значения кодированных пикселей.
Пожалуйста, предложите.
Заранее спасибо:)