protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp) { Color orig; Color steg; var size = originalBmp.Height*originalBmp.Width; var totalDifference = 0.0; var maxDifference = 0.0; double currentDifference; for (var y = 0; y < originalBmp.Height; y++) { for (var x = 0; x < originalBmp.Width; x++) { orig = originalBmp.GetPixel(x, y); steg = steganoBmp.GetPixel(x, y); currentDifference = Math.Pow(Math.Abs(orig.R) + Math.Abs(orig.G) + Math.Abs(orig.B), 2); if (currentDifference >= maxDifference) maxDifference = currentDifference; totalDifference += Math.Pow(Math.Abs(orig.R - steg.R) + Math.Abs(orig.G - steg.G) + Math.Abs(orig.B - steg.B), 2); } } return size*maxDifference/totalDifference; }
protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp) { Color orig; Color steg; var originalDiffernce = 0.0; var totalDifference = 0.0; for (var y = 0; y < originalBmp.Height; y++) { for (var x = 0; x < originalBmp.Width; x++) { orig = originalBmp.GetPixel(x, y); steg = steganoBmp.GetPixel(x, y); originalDiffernce += Math.Pow(Math.Abs(orig.R) + Math.Abs(orig.G) + Math.Abs(orig.B), 2); totalDifference += Math.Pow(Math.Abs(orig.R - steg.R) + Math.Abs(orig.G - steg.G) + Math.Abs(orig.B - steg.B), 2); } } return originalDiffernce/totalDifference; }
protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp) { var size = originalBmp.Height*originalBmp.Width; Color orig; Color steg; var difference = 0.0; for (var y = 0; y < originalBmp.Height; y++) { for (var x = 0; x < originalBmp.Width; x++) { orig = originalBmp.GetPixel(x, y); steg = steganoBmp.GetPixel(x, y); difference += Math.Abs(orig.R - steg.R) + Math.Abs(orig.G - steg.G) + Math.Abs(orig.B - steg.B); } } return difference/size; }
public static Bitmap ChangeColor(Bitmap src, Color color) { var result = new Bitmap(src); var lockBitmap = new LockBitmap(result); lockBitmap.LockBits(); var compareClr = Color.FromArgb(255, 255, 255, 255); for (var y = 0; y < lockBitmap.Height; y++) { for (var x = 0; x < lockBitmap.Width; x++) { if (lockBitmap.GetPixel(x, y) == compareClr) { lockBitmap.SetPixel(x, y, color); } } } lockBitmap.UnlockBits(); return result; }
/** * Does sample pairs analysis on an image. * * @param image The image to analyse. */ public double DoAnalysis(LockBitmap image, int colour) { //get the images sizes int imgx = image.Width, imgy = image.Height; int startx = 0, starty = 0; var apair = new Color[2]; int u, v; long P, X, Y, Z; long W; P = X = Y = Z = W = 0; //pairs across the image for (starty = 0; starty < imgy; starty++) { for (startx = 0; startx < imgx; startx = startx + 2) { //get the block of data (2 pixels) apair[0] = image.GetPixel(startx, starty); apair[1] = image.GetPixel(startx + 1, starty); u = GetPixelColour(apair[0], colour); v = GetPixelColour(apair[1], colour); //if the 7 msb are the same, but the 1 lsb are different if ((u >> 1 == v >> 1) && ((v & 0x1) != (u & 0x1))) W++; //if the pixels are the same if (u == v) Z++; //if lsb(v) = 0 & u < v OR lsb(v) = 1 & u > v if ((v == (v >> 1) << 1) && (u < v) || (v != (v >> 1) << 1) && (u > v)) X++; //vice versa if ((v == (v >> 1) << 1) && (u > v) || (v != (v >> 1) << 1) && (u < v)) Y++; P++; } } //pairs down the image for (starty = 0; starty < imgy; starty = starty + 2) { for (startx = 0; startx < imgx; startx++) { //get the block of data (2 pixels) apair[0] = image.GetPixel(startx, starty); apair[1] = image.GetPixel(startx, starty + 1); u = GetPixelColour(apair[0], colour); v = GetPixelColour(apair[1], colour); //if the 7 msb are the same, but the 1 lsb are different if ((u >> 1 == v >> 1) && ((v & 0x1) != (u & 0x1))) W++; //the pixels are the same if (u == v) Z++; //if lsb(v) = 0 & u < v OR lsb(v) = 1 & u > v if ((v == (v >> 1) << 1) && (u < v) || (v != (v >> 1) << 1) && (u > v)) X++; //vice versa if ((v == (v >> 1) << 1) && (u > v) || (v != (v >> 1) << 1) && (u < v)) Y++; P++; } } //solve the quadratic equation //in the form ax^2 + bx + c = 0 var a = 0.5*(W + Z); double b = 2*X - P; double c = Y - X; //the result double x; //straight line if (a == 0) x = c/b; //curve //take it as a curve var discriminant = Math.Pow(b, 2) - 4*a*c; if (discriminant >= 0) { var rootpos = (-1*b + Math.Sqrt(discriminant))/(2*a); var rootneg = (-1*b - Math.Sqrt(discriminant))/(2*a); //return the root with the smallest absolute value (as per paper) if (Math.Abs(rootpos) <= Math.Abs(rootneg)) x = rootpos; else x = rootneg; } else { x = c/b; } if (x == 0) { //let's assume straight lines again, something is probably wrong x = c/b; } return x; }
/** * Gets the RS analysis results for flipping performed on all * pixels. * * @param image The image to analyse. * @param colour The colour to analyse. * @param overlap Whether the blocks should overlap. * @return The analysis information for all flipped pixels. */ private double[] GetAllPixelFlips(LockBitmap image, int colour, bool overlap) { //setup the mask for everything... var allmask = new int[mM*mN]; for (var i = 0; i < allmask.Length; i++) { allmask[i] = 1; } //now do the same as the doAnalysis() method int startx = 0, starty = 0; var block = new Color[mM*mN]; double numregular = 0, numsingular = 0; double numnegreg = 0, numnegsing = 0; double numunusable = 0, numnegunusable = 0; double variationB, variationP, variationN; while (startx < image.Width && starty < image.Height) { //done once for each mask for (var m = 0; m < 2; m++) { //get the block of data var k = 0; for (var i = 0; i < mN; i++) { for (var j = 0; j < mM; j++) { block[k] = image.GetPixel(startx + j, starty + i); k++; } } //flip all the pixels in the block (NOTE: THIS IS WHAT'S DIFFERENT //TO THE OTHER doAnalysis() METHOD) block = FlipBlock(block, allmask); //get the variation the block variationB = GetVariation(block, colour); //now flip according to the mask block = FlipBlock(block, mMask[m]); variationP = GetVariation(block, colour); //flip it back block = FlipBlock(block, mMask[m]); //negative mask mMask[m] = InvertMask(mMask[m]); variationN = GetNegativeVariation(block, colour, mMask[m]); mMask[m] = InvertMask(mMask[m]); //now we need to work out which group each belongs to //positive groupings if (variationP > variationB) numregular++; if (variationP < variationB) numsingular++; if (variationP == variationB) numunusable++; //negative mask groupings if (variationN > variationB) numnegreg++; if (variationN < variationB) numnegsing++; if (variationN == variationB) numnegunusable++; //now we keep going... } //get the next position if (overlap) startx += 1; else startx += mM; if (startx >= image.Width - 1) { startx = 0; if (overlap) starty += 1; else starty += mN; } if (starty >= image.Height - 1) break; } //save all the results (same order as before) var results = new double[4]; results[0] = numregular; results[1] = numsingular; results[2] = numnegreg; results[3] = numnegsing; return results; }
/* * Does an RS analysis of a given image. * <P> * The analysis data returned is specified by name in * the getResultNames() method. * * @param image The image to analyse. * @param colour The colour to analyse. * @param overlap Whether the blocks should overlap or not. * @return The analysis information. */ public double[] DoAnalysis(LockBitmap image, int color, bool overlap) { int startx = 0, starty = 0; var block = new Color[mM*mN]; double numregular = 0, numsingular = 0; double numnegreg = 0, numnegsing = 0; double numunusable = 0, numnegunusable = 0; double variationB = 0, variationP = 0, variationN = 0; while (startx < image.Width && starty < image.Height) { //this is done once for each mask... for (var m = 0; m < 2; m++) { //get the block of data var k = 0; for (var i = 0; i < mN; i++) { for (var j = 0; j < mM; j++) { block[k] = image.GetPixel(startx + j, starty + i); k++; } } // get the variation the block variationB = GetVariation(block, color); //now flip according to the mask block = FlipBlock(block, mMask[m]); variationP = GetVariation(block, color); //flip it back block = FlipBlock(block, mMask[m]); //negative mask mMask[m] = InvertMask(mMask[m]); variationN = GetNegativeVariation(block, color, mMask[m]); mMask[m] = InvertMask(mMask[m]); //now we need to work out which group each belongs to //positive groupings if (variationP > variationB) { numregular++; } if (variationP < variationB) { numsingular++; } if (variationP == variationB) { numunusable++; } //negative mask groupings if (variationN > variationB) { numnegreg++; } if (variationN < variationB) { numnegsing++; } if (variationN == variationB) { numnegunusable++; } //now we keep going... } //get the next position if (overlap) startx += 1; else startx += mM; if (startx >= image.Width - 1) { startx = 0; if (overlap) { starty += 1; } else { starty += mN; } } if (starty >= image.Height - 1) { break; } } //get all the details needed to derive x... var totalgroups = numregular + numsingular + numunusable; var allpixels = GetAllPixelFlips(image, color, overlap); var x = GetX(numregular, numnegreg, allpixels[0], allpixels[2], numsingular, numnegsing, allpixels[1], allpixels[3]); //calculate the estimated percent of flipped pixels and message length double epf, ml; if (2*(x - 1) == 0) epf = 0; else epf = Math.Abs(x/(2*(x - 1))); if (x - 0.5 == 0) ml = 0; else ml = Math.Abs(x/(x - 0.5)); //now we have the number of regular and singular groups... var results = new double[28]; //save them all... //these results results[0] = numregular; results[1] = numsingular; results[2] = numnegreg; results[3] = numnegsing; results[4] = Math.Abs(numregular - numnegreg); results[5] = Math.Abs(numsingular - numnegsing); results[6] = numregular/totalgroups*100; results[7] = numsingular/totalgroups*100; results[8] = numnegreg/totalgroups*100; results[9] = numnegsing/totalgroups*100; results[10] = results[4]/totalgroups*100; results[11] = results[5]/totalgroups*100; //all pixel results results[12] = allpixels[0]; results[13] = allpixels[1]; results[14] = allpixels[2]; results[15] = allpixels[3]; results[16] = Math.Abs(allpixels[0] - allpixels[1]); results[17] = Math.Abs(allpixels[2] - allpixels[3]); results[18] = allpixels[0]/totalgroups*100; results[19] = allpixels[1]/totalgroups*100; results[20] = allpixels[2]/totalgroups*100; results[21] = allpixels[3]/totalgroups*100; results[22] = results[16]/totalgroups*100; results[23] = results[17]/totalgroups*100; //overall results results[24] = totalgroups; results[25] = epf; results[26] = ml; results[27] = image.Width*image.Height*3*ml/8; return results; }