在MATLAB中恼人的bug

时间:2014-02-22 15:05:43

标签: image matlab

我正在做一个项目,我需要编写两个函数。第一个是mk_key,其工作是将24 RGB图像转换为由连续字节组成的向量,后跟由4个字节组成的预告片,其中包含用于重建的图像尺寸(因此矢量大小为[1 m * n *] 3 + 4])然后根据种子值(像密码一样)随机混洗该向量的元素,最后使用hexa字节将向量保存到文件中;另一个函数是use_key,它用于从密钥文件重建图像,这是通过将矢量元素重新排列回其位置,然后使用预告片中的数据重建完整的RGB图像来完成的。我唯一的问题是重建的图像大部分像素丢失,它只显示图像的1/6左右,只有红色平面,其他平面的字节显示为灰色。

mk_key:

function mk_key(img, dest_file, seed)
s=size(img);
m=s(1);
n=s(2);
rg = zeros([1 m*n 3],'uint8');


 for i=drange(1:m)
    for j=drange(1:n)
    rg(1,n*i+j-n,:)=img(i,j,:); %convert rectangular image matrix into row image
    end
 end


rgf = zeros([1 (m*n*3)+4],'uint8');
for x=drange(1:3)
    rgf(1,(m*n*(x-1))+1:m*n*x)=rg(1,1:m*n,x);
end


mm=uint16(m);
nn=uint16(n);

rgf(1,(m*n*3)+1)=uint8(bitand(mm,hex2dec('00ff')));
rgf(1,(m*n*3)+2)=uint8(bitshift(bitand(mm,hex2dec('ff00')),-8));
rgf(1,(m*n*3)+3)=uint8(bitand(nn,hex2dec('00ff')));
rgf(1,(m*n*3)+4)=uint8(bitshift(bitand(nn,hex2dec('ff00')),-8));

rng(seed); 
idxs = randperm(((m*n*3)+4)); % generate a random sequence representing byte locations

sg = zeros([1 ((m*n*3)+4)],'uint8');
for i=drange(1:((m*n*3)+4))
sg(1,i)=rgf(1,idxs(i));
end


f = fopen(dest_file, 'w'); 
for i=drange(1:((m*n*3)+4))
    fprintf(f, '%x %x', sg(1,i));
end
fclose('all');
end

use_key:

function [img]=use_key(source_file, seed)
key_file=fopen(source_file);
key=fscanf(key_file,'%x %x');
key=key'; %Transpose column vector into row vector
key=uint8(key);
s=size(key);
rng(seed); 
idxs = randperm(s(2)); % generate a random sequence representing byte locations
mgf = zeros([1 s(2)],'uint8');
for i=drange(1:s(2))
    mgf(1,idxs(i))=key(1,i);
end

m=uint16(mgf(1,s(2)-3))+uint16(mgf(1,s(2)-2))*(16^2);
n=uint16(mgf(1,s(2)-1))+uint16(mgf(1,s(2)))*(16^2);

img = zeros([m n 3],'uint8');    

for x=drange(1:3)
   for i=drange(1:m)
       for j=drange(1:n)
       img(i,j,x)=mgf(1,(n*i+j-n)+(m*n)*(x-1));%convert row matrix into rectangular image matrix
       end
   end
end

fclose('all');
end

1 个答案:

答案 0 :(得分:2)

无论是什么错误,在那些可怕的嵌套循环中它都是某处。我没有尝试修复看起来像C代码的直接端口,而是开始清理所有令人困惑和不必要的过度复杂的位,以便我能理解它;当我完成时,剩下的不多了:

function mk_key(img, dest_file, seed)
s = uint16(size(img));
s = typecast(s(1:2), 'uint8');
rg = reshape(img, 1, []);
rgf = [rg s];

rng(seed);
idxs = randperm(numel(rgf));
sg = rgf(idxs);

f = fopen(dest_file, 'w');
fprintf(f, '%x ', sg);
fclose(f);
end

并相应地:

function [img] = use_key(source_file, seed)
key_file = fopen(source_file);
key = fscanf(key_file,'%x');
fclose(key_file);

rng(seed);
idxs = randperm(numel(key));
mgf = zeros(1, numel(key), 'uint8');
mgf(idxs) = key;

s = typecast(mgf(end-3:end), 'uint16');
img = reshape(mgf(1:end-4), s(1), s(2), 3);
end

虽然reshape的排序与你的循环相比有所不同,但是假设矢量随后被洗牌,这没有实际的区别 - 它更健壮,按预期工作并且速度更快。