是否可以将图像的所有像素变为黑色并在以后恢复原始图像?

时间:2011-03-08 07:46:36

标签: matlab

将图片视为任何视频的帧。我正在为有线电视的按次付费电视系统开发代码,这就是为什么我想在发送器端使用密钥来进行bitxor(按位xor) RGB像素或只有一种颜色可以做一些导致黑色或白色屏幕的颜色。我已经写了这段代码,但我仍然可以看到那些像素颜色分散的图片。

我想使用一些技术,通过这种技术,图片变成黑色或白色,以保护我的视频免受取消订阅者的影响,并从此黑白图片中恢复原始图片供以后使用。

img=imread('pepper.png');
[imr,imc,clr]=size(img);

for row=1:imr
    for col=1:imc
        for k=1:clr             
          if(k==1) 
             img2(row,col,k)=bitxor(img(row,col,k),66);
          else
             img2(row,col,k)=img(row,col,k);   
          end
        end
    end
end
imwrite(img2,'pepper.png');
imshow(img2); 

5 个答案:

答案 0 :(得分:4)

严格来说:不。存储黑色(即颜色#000000)时,无法恢复以前的内容。

然而,您可以将数据存储在其他位置,例如在元数据中,但我想知道会有什么好处。

我怀疑你只希望你的图像肉眼看起来像黑色。这可以以成本(大小,信息丢失或可见性)来完成。你可以做一些直观的事情:

  1. 非常有损:只需将所有颜色调成非常接近黑色的颜色,但根据图像的内容,您只需在图像更亮/更暗的位置放置一个稍亮或更暗的黑色。这样图像看起来是黑色的,但你可以恢复一些信息(显然不是原版的精确复制品)。通过这种方式,我希望您能够为每种颜色存储1​​或2位每个像素(而不是原始图像中的8位)
  2. 只是前一个原则的一小部分延伸。如果您想要完美重建并允许您的图像大小增长,这是可能的。您只需将原始图像中的1个像素映射到“黑色”图像中的4,9,16 ......像素。例如。如果您选择9个像素,则将原始图像的第一个位平面存储在第一组像素中,将第二个位平面存储在第二个像素中,...(并且第9个像素组仅为黑色)。
  3. 你当然可以设计一些方案来混合周围的像素,这样只看几乎黑色图像的位平面就不会产生任何视觉线索。在重建图像时,您将不得不改变它。

    显然,这些例子只是快速做这种事情的方法,任何熟悉steganography的人都会知道这些技巧(当然还有更好的技巧),并且如果他们怀疑某些事情,可能会尝试将它们反转。< / p>

答案 1 :(得分:3)

恢复被破坏的信息是不可能的,如果可能的话,为什么有人会存储彩色图像呢?

重新编辑:如果您使用XOR(或任何其他任意操作)来获取(我犹豫地称之为加密)纯黑色或白色图像,这意味着“解密”所需的信息是原始图像本身(因为只有(a XOR b) XOR b = a,除非您使用某些mod操作或类似操作。但是,为什么不简单地使用现有的加密之一将加密图像渲染成看似垃圾?另外,请查看维基百科在Conditional access上的条目,以获得一些灵感。

答案 2 :(得分:1)

这让我想起2008年对Underhanded C竞赛的挑战:http://underhanded.xcott.com/?p=8

答案 3 :(得分:1)

这是我的愚蠢解决方案,但它足以满足我的需求: 不是在Matlab中,而是一种加扰图像的通用算法。

private void BitmapObfuscator(ref Bitmap img, bool obfuscate)
{
    BitmapData d = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    for (int y = 0; y < d.Height; y++) {
        unsafe
        {
            byte* row = (byte*)d.Scan0 + (y * d.Stride);
            for (int x = 0; x < d.Stride; x+=d.Stride / d.Width) {
                byte* pixelR = row + x;
                byte* pixelG = row + x + 1;
                byte* pixelB = row + x + 2;
                int shift = (x * y) % 10;
                if (shift > 8) shift = 4;
                switch (shift) {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                        *pixelR = (byte)(255 - *pixelR);
                        *pixelG = (byte)(255 - *pixelG);
                        *pixelB = (byte)(255 - *pixelB);
                        break;
                }
                int pixel = *pixelR << 16 | *pixelG << 8 | *pixelB;

                if (obfuscate)
                {
                    pixel = pixel << 4;
                    byte surplus = (byte)(pixel >> 24);
                    pixel |= surplus;
                }
                else {
                    byte surplus = (byte)(*pixelB & (byte)0x0F);
                    pixel = pixel >> 4; 
                    pixel |= surplus << 20;
                }
                *pixelR = (byte)(pixel >> 16);
                *pixelG = (byte)(pixel >> 8 & 0x000000FF);
                *pixelB = (byte)(pixel & 0x000000FF);
            }
        }
    }
    img.UnlockBits(d);
}

它足以使图片变得无法识别,但算法可以取回原始图像。

也许它可以帮助你,我相信你可以用某种方式将它翻译成mathlab。

如果您想知道为什么'切换':这种方法容易受到少量彩色图像的影响,这就不那么容易了。

这些是输出: garbled output

答案 4 :(得分:0)

您必须保留彩色图像的副本。

rgb_I = imread('yourcolorimage.jpg');
gray_I = rgb2gray(rgb_I);
imwrite(gray_I,'yourblackimage.jpg');
imshow(rgb_I);