Is there a way to make the Bit rotation operation reversible? I mean, if there is an image X (size 256 * 256 *3) then on doing bit rotation, image Y is obtained. Then on subjecting Y to a bit rotation, we get back image X. Also, How to tackle the bit overflow so that there is no information loss.
UPDATE: I've taken the code I posted below and refined it into a complete function with error-checking, help documentation, and the ability to operate on arrays of unsigned integers and double-precision variables just like the related built-in function BITSHIFT. I suggest using the newer version I link to above instead of the older version posted below.
MATLAB does not have a built-in bit rotation function, and the BITSHIFT function will drop bits that overflow. However, you could implement your own bit rotation function based on the existing bit operations. Here's a simple first-pass version I threw together (sans error-checking):
function data = bit_rotate(data,nBits)
dataBits = log2(double(intmax(class(data)))+1); %# Number of bits in data
nBits = rem(nBits,dataBits); %# No need to rotate by dataBits bits or more
if nBits == 0 %# No bit rotation needed, just return
return
end
shiftedData = bitshift(data,nBits); %# Bit shift the data
lostData = bitxor(data,bitshift(shiftedData,-nBits)); %# Find the lost bits
rotatedData = bitshift(lostData,nBits-sign(nBits)*dataBits); %# Rotate them
data = shiftedData+rotatedData; %# Add the rotated bits to the shifted bits
end
And here's some test data:
>> B = uint8(208); %# An unsigned 8-bit integer value
>> disp(dec2bin(B,8)) %# Display the bit pattern of B
11010000
>> disp(dec2bin(bit_rotate(B,2),8)) %# Rotate left by 2 bits
01000011
>> disp(dec2bin(bit_rotate(B,-2),8)) %# Rotate right by 2 bits
00110100
Note that bit_rotate will also operate on any size matrix input for data as long as it's an unsigned integer type.
Sure, bit rotation is reversible, just rotate the other way around by the same amount.
Wikipedia has nice info on how to implement it in C with basic bit shifts so that you don't get overflow:
http://en.wikipedia.org/wiki/Circular_shift
And I suppose that if the operation is called "bit rotation" in Matlab, it surely doesn't overflow anyway.
Related
I am using MATLAB- CVST to perform Stereo Camera Calibration. From 28 images (6 X 7 corners), stereoParams are obtained (stereoParams.MeanReprojectionError = 0.3168).
Next, I took took a checkerboard stereo pair (CB_I1 & CB_I2).
To CB_I1 I applied the following functions:
undistortImage
detectCheckerboardPoints
generateCheckerboardPoints
extrinsics: This gives me Translation vector (T) and Rotation Matrix (R)
Next, To both CB_I1 & CB_I2, I apply the following functions:
undistortImage
detectCheckerboardPoints
triangulate: this gives me worldPoints
Inverse Translation and Rotation Transform
This is my code:
CB_I1_undist = undistortImage(CB_I1, stereoParams.CameraParameters1);
CB_I2_undist = undistortImage(CB_I2, stereoParams.CameraParameters2);
[imagePoints1, ~] = detectCheckerboardPoints(CB_I1_undist);
[imagePoints, ~] = detectCheckerboardPoints(CB_I2_undist);
worldPoints = triangulate(imagePoints1,imagePoints,stereoParams);
Translated_pnts = zeros(size(worldPoints));
Translated_pnts(:,1) = worldPoints(:,1) - T(1);
Translated_pnts(:,2) = worldPoints(:,2) - T(2);
Translated_pnts(:,3) = worldPoints(:,3) - T(3);
Rotated_pnts = Translated_pnts * (R');
Transformed_points = Rotated_pnts;
Ultimately, Transformed_points looks like this:
and so on....for 42 points.
How do I interpret this? I expect Transformed_points to be:
since each square size is 40mm.
Primarily, is this an error?
What is the cause? Is it because of the high reprojection error? (if so, how can it be minimised?)
How can I reduce this as much as possible?
I want this as close as possible to the ideal value. What are the different ways by which I can improve my algorithm's accuracy?
Let me know if you need any other information.
You say you have a mean re-projection error of 0.3~.
If I calculate the distance between your first and second point:
sqrt((-0.2006+0.1993)^2+(-1.2843-39.1922)^2+(3.0466-2.0656)^2)
ans >>
40.4884
Well thats what you expect right? Its not 100% accurate of course.
Also,look again at your points. They are exactly where you expect them to be. Instead of 120 you have 120.06. Instead of 160, you have 159.94.
you are missing the points by around 0.3 millimeters. 0.3 MILIMETERS.
Take a ruler and try to measure 0.3 millimeters!!
Thats 4 time a human hair!
Its more or less the minimum distance the human eye can distinguish!
3 times the with of paper!
0.6 times the size OF A BACTERIA! (amoeba Proteus)
WOW, I think thats a quite good error to have, dont you?
Anyway, you can decrease that error using more calibration images, but yeah, I'd say you are doing a good job already.
A good way of measuring the error so it has more meaning is to calculate the pixel error, not the real physical error. If you divide the error by the length of a pixel, you can know how many pixels of error you have. You will see that most likely in your case you are having sub-pixel accuracy (pixel error < 1). This is very good because it means that your error is smaller than what you can measure, so, in some sense (not really, but yeah) you are breaking the Shanon principle! Good job
Source of random data: http://www.wolframalpha.com/input/?i=300+micrometres
To Ander's answer I would just like to add that you should be sure to measure the square size very precisely, using a caliper. If you can get sub-millimeter accuracy on that, that will have an effect on your reconstruction accuracy. Also, please be sure not to use lossy compression on your images, i. e. no jpeg. Jpeg artifacts will also decrease your accuracy.
I'm trying to make a histogram out of a DICOM file, but for the life of me I still can't figure out why I'm getting a negative value for an index. I've transposed the image but the index is still negative and I'm not sure what I am doing wrong. The values should be all correct for the file size, header, depth, and width, and the program I'm trying to process this in is MATLAB.
clear
fpointer=fopen('PIG_CT','r');
fseek(fpointer,980,'bof');
img=zeros(512,512);
img(:)=fread(fpointer,(512*512),'short');
img=transpose(img);
depth = 16;
width = depth/64;
fmax = max(max(img));
fmin = min(min(img));
hist64 = zeros(64,1);
for i = 1:512
for j = 1:512
rho = img(i,j);
b64 = floor(rho/width+1)+1;
hist64(b64,1)= hist64(b64,1)+1;
end
end
bar(hist64)
ERROR: Attempted to access hist64(-4094,1); index must be a positive integer or logical.
The equation that I am also using with this is:
Bin Width = (Image Depth)/(# of Bins)
I'm not familiar with MATLAB, but it looks like you're just reading the file from a specific seek point. Using a DICOM toolkit would ensure you get the actual pixel data attribute entry hand handle any encoding you're likely to run into.
Also, check if your DICOM reader is applying the rescale slope and intercept. Typically this will convert a CT image to Hounsfield units, which have negative values (though -4094 seems a bit much given air is -1000).
i am doing BPCS STEGANOGRAPHY.. i have separate secret blocks (4096- 8*8 blocks) and conjugation block( 64 - 8*8 blocks) ready for embedding. each can be accessed separately by calling
secret_block(:,:,1),
secret_block(:,:,2),
secret_block(:,:,3)
etc and
conju_block(:,:,1),
conju_block(:,:,2),
conju_block(:,:,3)
etc
During bpcs embedding cover image is bitplane sliced and stored as c1( lsb plane ),c2,c3,c4 c5,c6,c7,c8 (msbplane). I need to select lsb bit plane to msb plane and dividing each bitplane into 8*8 block, selected_block(:,:,i)) and among them complex blocks are replaced with initially secret_block (:,:,i) and later on conju_block(:,:,i) etc until all the 4096+64 blocks reached..
Please anyone tell me how replace on particular block of selected_block(:,:,i) with another block (conju_block(:,:,i) or secret_block(:,:,i)) ? Is it possible to use replace_block() for the same ,then what does 'sys' parameter means ????
I would start by putting all bit planes in one cell,
C{1} = c1;
C{2} = c2;
etc
so you can go through the bit planes in an automated manner.
for i = 1:8
curr_plane = C{i};
end
There are many ways to split a 2D array into blocks. A convenient one is mat2cell. The web documentation gives you a visual example of how it works.
Note that since you want 8x8 blocks, both the rows and columns must be exactly divisible by 8. You have 3 options:
only allow images with number of rows and columns divisible by 8,
automatically rescale images to such a size, or
take the biggest slice of the image matrix with such a size, do your steganography and put that modified image back into your slice of the original image, from where it came from.
We continue with the assumption that you have an image with number of rows and columns divisible by 8. Let's call your initial cover image cover.
row = size(cover, 1)/8;
col = size(cover, 2)/8;
blocks = mat2cell(curr_plane, ones(1, row)*8, ones(1, col)*8);
blocks is now a cell which holds all the 8x8 blocks of your bit plane, curr_plane. For example, if your bit plane had a size of 16x48, you now have 2x6 blocks. You can iterate through them simply with
for bi = 1:size(blocks,1)
for bj = 1:size(blocks,2)
my_8x8_block = blocks{bi,bj};
end
end
You're almost there. To sum up what we've done, we go from bit plane to bit plane and split each one in 8x8 blocks. Now, for every my_8x8_block, you can feed it into a function which calculates whether it's complex enough or not. If it is, you can simply overwrite it with the kth secret or conjugate block.
blocks{bi,bj} = secret_block(:,:,k);
Finally, once you have gone through a whole bit plane, you can put back the blocks to construct the modified bit plane
C{i} = cell2mat(blocks);
We were recently taught the concepts of error control coding - basic codes such as Hamming code, repeatition code etc.
I thought of trying out these concepts in MATLAB. My goal was to compare how an audio file plays when corrupted by noise and in the case when the file is protected by basic codes and then corrupted by noise.
So I opened a small audio clip of 20-30 seconds in MATLAB using audioread function. I used 16 bit encoded PCM wave file.
If opened in 'native' format it is in int16 format . If not it opens in a double format.
I then added two types of noises to it : - AWGN noise (using double format) and Binary Symmetric Channel noise (by converting the int16 to uint16 and then by converting that to binary using dec2bin function). Reconverting back to the original int16 format does add a lot of noise to it.
Now my goal is to try out a basic repeatition code. So what I did was to convert the 2-d audio file matrix which consists of binary data into a 3-d matrix by adding redundancy. I used the following command : -
cat(3,x,x,x,x,x) ;
It created a 3-D matrix such that it had 5 versions of x along the 3rd dimension.
Now I wish to add noise to it using bsc function.
Then I wish to do the decoding of the redundant data by removing the repetition bits using a mode() function on the vector which contains the redundant bits.
My whole problem in this task is that MATLAB is taking too long to do the computation. I guess a 30 second file creates quite a big matrix so maybe its taking time. Moreover I suspect what I am doing is not the most efficient way to do it with regards to the various data types.
Can you suggest a way in which I may improve on the computation times. Are there some functions which can help do this basic task in a better way.
Thanks.
(first post on this site with respect to MATLAB so bear with me if the posting format is not upto the mark.)
Edit - posting the code here :-
[x,Fs] = audioread('sample.wav','native'); % native loads it in int16 format , Fs of sample is 44 khz , size of x is 1796365x1
x1 = x - min(x); % to make all values non negative
s = dec2bin(x); % this makes s as a 1796365x15 matrix the binary stream stored as character string of length 15. BSC channel needs double as the data type
s1 = double(s) - 48; % to get 0s and 1s in double format
%% Now I wish to compare how noise affects s1 itself or to a matrix which is error control coded.
s2 = bsc(s,0.15); % this adds errors with probability of 0.15
s3 = cat(3,s,s,s,s,s) ; % the goal here is to add repetition redundancy. I will try out other efficient codes such as Hamming Code later.
s4 = bsc(s3,0.15);% this step is taking forever and my PC is unresponsive because of this one.
s5 = mode(s4(,,:)) ; % i wish to know if this is a proper syntax, what I want to do is calculate mode along the 3rd dimension just to remove redundancy and thereby reduce error.
%% i will show what I did after s was corrupted by bsc errors in s2,
d = char(s2 + 48);
d1 = bin2dec(d) + min(x);
sound(d1,Fs); % this plays the noisy file. I wish to do the same with error control coded matrix but as I said in a previous step it is highly unresponsive.
I suppose what is mostly wrong with my task is that I took a large sampling rate and hence the vector was very big.
using im2col sliding window in matlab i have converted the input image block into column and again by using col2im i do the inverse process but the output is not same as the input image. How can i recover the input image? can anyone please help me.
Here is the code
in=imread('tire.tif');
[mm nn]=size(in);
m=8;n=8;
figure,imshow(in);
i1=im2col(in,[8 8],'sliding');
i2 = reshape( sum(i1),mm-m+1,nn-n+1);
out=col2im(i2,[m n],[mm nn],'sliding');
figure,imshow(out,[]);
thanks in advance...
You didn't specify exactly what the problem is, but I see a few potential sources:
You shouldn't expect the output to be exactly the same as the input, since you're replacing each pixel value with the sum of pixels in an 8-by-8 neighborhood. Also, you will get a shrinkage of the resulting image by 7 pixels in each direction (i.e. [m-1 n-1]) since the 'sliding' option of IM2COL does not pad the array with zeroes to create neighborhoods for pixels near the edges.
These two lines are redundant:
i2 = reshape( sum(i1),mm-m+1,nn-n+1);
out=col2im(i2,[m n],[mm nn],'sliding');
You only need one or the other, not both:
%# Use this:
out = reshape(sum(i1),mm-m+1,nn-n+1);
%# OR this:
out = col2im(sum(i1),[m n],[mm nn],'sliding');
Image data in MATLAB is typically of type 'uint8', meaning each pixel is represented as an unsigned 8-bit integer spanning the range 0 to 255. Assuming this is what in is, when you perform your sum operation you will implicitly end up converting it to type 'double' (since an unsigned 8-bit integer will likely not be big enough to hold the sum totals). When image pixel values are represented with a double type, the pixel values are expected to span the range 0 to 1, so you will want to scale your resulting image by its maximum value to get it to display properly:
out = out./max(out(:));
Lastly, check what kind of input image you are using. For your code, you are essentially assuming in is 2-D (i.e. a grayscale intensity image). If it is a truecolor (i.e. RGB) image, the third dimension is going to cause you some trouble, and you will have to either process each color plane separately and recombine them or convert the RGB image to grayscale. If it is an indexed image (with an associated color map), you will not be able to do the sort of processing you describe above without first converting it to a grayscale representation.
Why are you expecting the output to be the same?
i2 is the result of performing a SUM around a pixel neighborhood (essentially a low-pass filter), which is the final blurry image that you see. i.e you are NOT doing an inverse process with the COL2IM call.
i1 obtained from 'sliding' option has the information that you would get from 'distinct' option as well, which you need to filter out. Now, this may not be the best way to code it up but it works. Assume that mm is a multiple of m and nn is a multiple of n. If this is not the case, then you'll have to zero-pad accordingly to make this the case.
in=imread('tire.tif');
[mm nn]=size(in);
m=8;n=8;
i1 = im2col(in,[m,n],'sliding');
inSel = [];
for k=0:mm/m-1
inSel = [inSel 1:n:nn+(nn-n+1)*n*k];
end
out = col2im(i1(:,inSel),[m,n],[mm,nn],'distinct');