I can't get the bit 2 in MatLab
for example:
enter code here
% c is an array to save the get bit result
a is decimal = 253
convert it to binary
a=11111101
k=1;
c(k)=bitget(a,2);
c=0;
what I need is c(1)=0;
You need bin2dec and bitget.
The code, you need to use is bitget(a,2) rather then getbit, and its little endian, so its looking from the right, meaning bit number 2 will return 0
Updating answer to updated question: again, you still need to be using the bitget command,
and it is NOT looking at the bits from the left, it is looking at them from the right.
For example if your bits were a=11110000:
bitget(a,1) = 0
bitget(a,2) = 0
bitget(a,3) = 0
bitget(a,4) = 0
bitget(a,5) = 1
bitget(a,6) = 1
bitget(a,7) = 1
bitget(a,8) = 1
I hope this helps
3rd update:
dec2bin will always return string values unfortunately, so I checked to see, if they output the value in vectors and for that you can use de2bi, so for example then
253 will look like x = [1, 1, 1, 1, 1, 1, 0, 1], and if you want to access a particular location then you can just do x[y] and have your number, I hope this helps.
Related
>> a = 255
a =
255
>> bitset(a,1,0)
ans =
254
here the first bit is set to 0 so we get 11111110 equivalent to 254
>> bitset(a,[1,2],0)
ans =
254 253
here the 1st bit and 2nd bit are being set to 0 seperately. Hence we get
11111110 equivalent to 254
11111101 equivalent to 253
how to get 11111100 equivalent to 252?
Apply bitset twice:
bitset(bitset(a, 1, 0), 2, 0)
The order of application should not matter.
Alternatively, you can use the fact that bitset is an equivalent to applying the correct sequence of bitand, bitor and bitcmp operations.
Since you are interested in turning off multiple bits, you can do
bitand(bitset(a, 1, 0), bitset(a, 2, 0))
Here's a one-liner:
a = 255;
bits = [1,2];
bitand(a,bitcmp(sum(2.^(bits-1)),'uint32'))
Taken apart:
b = sum(2.^(bits-1))
computes the integer with the given bits set. Note that bits must not contain duplicate elements. Use unique to enforce this: bits = unique(bits).
c = bitcmp(b,'uint32')
computes the 32-bit complement of the above. ANDing with the complement resets the given bits.
bitand(a,c)
computes the binary AND of the input number and the integer with the given bits turned off.
Setting bits is easier:
a = 112;
bits = [1,2];
bitor(a,sum(2.^(bits-1)))
Maybe most explicit, easiest to understand, you can convert to a string representing binary and then do the operations there, then convert back.
a = 255
bin_a = flip(dec2bin(a)) % flip to make bigendian
bin_a([1, 2]) = '0'
a = bin2dec(flip(bin_a))
Here is a little recursive function based on the answer from #Mad Physicist that will allow zeroing of any number of bits in data . Thanks for the original info. The recursion is probably dead obvious to most people but it might help somebody out.
function y = zero_nbits(x, n)
y = bitset(x, n, 0)
if n > 1
y = zero_nbits(y, n-1);
end
end
Say i have a 2D matrix A:
A = [ 1 1 0 0
1 0 0 0
1 1 1 0];
A is not necessarily binary, or even integer (i.e., floats are possible). I want to remove any column that contains uniform valued elements. In the above example, i would get:
1 0
0 0
1 1
To make this fully general, i'd like to allow the user to select the dimension along which rows/columns/slices are removed (i.e., with a DIM option).
Any ideas?
You could try using the min and max functions, which allow you to use the dim argument.
For example
index = min(A,[],1)==max(A,[],1);
A(:,index)=[];
will remove the columns you want. It is straightforward to do the same for rows
index = min(A,[],2)==max(A,[],2);
A(index,:)=[];
One-liner:
B = A(:,range(A)~=0); %//columns
The other one-liner is not that nice, and ugly one-liners should not be written down. :-) But is basically the same solution as S..'s, except is way more expensive (requires stats toolbox).
Please note that "generality" of subscript-based solutions doesn't extend to N-dimensional arrays as easily, because subscripting in ND arrays without checking beforehand the number of dimensions is difficult. Also, for the 1D arrays the notion of "uniformity" is a bit odd along the singleton dimension (the result is always empty).
Besides the neat solution provided by #S.. there is this simple hack also for your example:
for ii = 1:size(A,2)
T(ii) = all(A(:,ii) == sum(A(:,ii))/numel(A(:,ii)));
end
A(:,~T)
ans =
1 0
0 0
1 1
As suggested by #gariepy the right side of the equation can be replaced with mean function.
for ii = 1:size(A,2)
T(ii) = all( A(:,ii) == mean(A(:,ii)) );
end
A(:,~T)
A(:,~all(A == repmat(A(1,:),[size(A,1) 1])))
Inspired by #S.. but only checks if every element of the column equals the first element of the column. Seems like a little less work for the processor than finding the min and the max, and checking for equality.
So here is what I was trying to do. I'm absolutely new to matlab. It has only been a day or so that I've used it and here is a little something that my teacher had asked me to do. Embed statements or group of strings within an image using the LSB Algorithm. The string is to be read from a file.
As of now, I've not used any file operations. I'm trying this using one character and I don't know whats wrong. The algo seems simple but my output i.e, both the cover and the steg pixels show the same value. :(
cover=imread('D:\l.jpg');
steg=cover;
l=1;
LSB=0;
height = size (cover, 1);
width = size (cover, 2);
message = 'J' ;
mdec = uint8(message);
mbin = dec2bin(mdec, 8);
mbins= mbin(:);
len=length(mbins);
for i = 1:height
for j = 1:width
if(l<=len)
LSB = mod(cover(i,j), 2);
if(mbins(l)==LSB)
steg(i,j) = cover(i,j);
else if (mbins(l)~=LSB && LSB==1 && mbins(l)==0)
steg(i,j) = cover(i,j)-1;
else if (mbins(l)~=LSB && LSB==0 && mbins(l)==1)
steg(i,j) = cover(i,j)+1;
end
end
end
l=l+1;
end
end
end
imwrite(steg,'D:\hidden.jpg');
%imshow(steg)
cover(1, 1:8)
steg(1, 1:8)
Oh, nested loops... that's not the way to go.
You want to replace the least significant bits of the first l pixels with the binary ascii representation of your input string.
First thing that went wrong - converting char to binary:
Converting a character to its binary representation should be done using bitget
>> bitget( uint8('J'), 1:8 )
0 1 0 1 0 0 1 0
Gives back 1-by-8 binary array, while using dec2bin:
>> dec2bin( uint8('J'), 8 )
01001010
Gives back 1-by-8 string: the actual numeric values of this array are
>> uint8(dec2bin( uint8('J'), 8 ))
48 49 48 48 49 48 49 48
Can you appreciate the difference between the two methods?
If you insist on using dec2bin, consider
>> dec2bin( uint8('J'), 8 ) - '0'
0 1 0 0 1 0 1 0
Second point - nested loops:
Matlab favors vector/matrix vectorized operations rather than loops.
Here's a nice way of doing it without loops, assuming cover is a gray scale image (that is it has a single color channel rather than 3) of type uint8.
NoLsb = bitshift( bitshift( cover, -1 ), 1 ); %// use shift operation to set lsb to zero
lsb = cover - NoLsb; %// get the lsb values of ALL pixels
lsb( 1:l ) = mbins; %// set lsb of first l pixels to bits of message
steg = NoLsb + lsb; %// this is it!
This is how I do it with arrays where binaries are stored
>> hhh=[1 0 1 0 1 0 0; 0 0 1 0 0 0 0; 1 0 1 0 0 0 0; 0 0 0 1 1 0 1]; find(hhh(:,1)==1)
ans =
1
3
and now I am trying to understand how to do it with binary numbers
>> hhhh=[1010100; 0010000; 1010000; 0001101]; find(hhhh(:,1)==1)
ans =
Empty matrix: 0-by-1
where the hack to break up all binaries back into arrays can work (ismember('101010','1') and then prepending with zeros) but I feel there is probably some better alternative so
By which command to check whether Nth bit active in binary number?
P.s. Harder puzzle: is there a type-agnostic solution that would work with both binaries and DEC?
String Input
If you have a string input, you can get away with testing for char equality:
find(hhh(:, 1) == '1')
for string arrays (i.e char matrices), you can extract both outputs of find (rows and columns) to be able to determine which active bit corresponds to which string:
[r, c] = find(hhh == '1');
Numeric Input
For numeric inputs, you can use bitget to get the binary representation. From there, it's very similar to the solution for string inputs:
B = bsxfun(#bitget, hhh, size(hhh, 1):-1:1);
[r, c] = find(B);
Note that find searches for non-zero elements, so there's no need to write find(B == 1) explicitly.
Combined Solution
If the solution for the "harder puzzle" is what you're after, you can determine the type of the input first, and handle it accordingly:
if ischar(hhh)
%// Apply solution to string array
%//...
else if isnumeric(hhh)
%// Apply solution to numeric input
%// ...
else
%// This type is unsupported
assert('Matrix is of unsupported type')
end
Repeating my comment in form of an answer:
There's no need to work with the string/array-like representation of the bits in this case.
You can use bitget right on the output of find(mlf). Like:
filled = find(mlf);
filled_and_bit2 = filled(logical(bitget(filled,2)));
You should store your binary number as a string matrix:
hhhh=['1010100'; '0010000'; '1010000'; '0001101'];
Then you can do
find(bin2dec(hhhh) >= bin2dec('1000000'))
returns:
ans =
1
3
or you could use the less intuitive (but probably faster)
find(hhhh(:,1)-'0') %// Or find(hhhh(:,1)=='1') as EitanT points out
to get the same result.
This is not a direct answer to the question but related -- good point by Sebastian in a comment! So suppose that the binaries are indices. Now instead of playing with dec2bin something like
>> hhh=dec2bin(find(mlf));B=bsxfun(#bitget, hhh, 8:-1:1);find(B)
Error using bsxfun
Non-singleton dimensions of the two input arrays must match each other.
we can directly address the indices like
>> filled = find(mlf);
filled_and_bit2 = bitget(filled,1);
filled(logical(filled_and_bit2))
ans =
1
7
where it finds the binaries with the first active bit.
Procedure
Data
>> mlf=sparse([],[],[],2^31,1);
mlf(1)=7;
mlf(4)=10;
mlf(7)=-1;
>> mlf
mlf =
(1,1) 7
(4,1) 10
(7,1) -1
>> find(mlf)
ans =
1
4
7
Interpret the index numbers as binary
(1,1) -----> 000001
(4,1) -----> 000100
(7,1) -----> 000111
Examples
Output 1: find cases where 3th bit is active
4
7
Output: find cases where 1st bit is active
1
7
Output: find cases where 2nd bit is active
4
So basically this is what I want to do:
I have the decimal value 3 as such:
x=3
Now i get the binary format as such:
s = dec2bin(x,3)
s = 011
The format of s is a string (correct?).
Now I would like to convert this value to a matrix, in order to do matrix operations on it. As such:
A = [0 1 1]
But I cannot seem to get this right. I have tried both str2mat and cell2mat but no results. Any ideas?
If you are 100% certain you will only be getting 0s and 1s, use:
a = '001';
b = double(a)-48;
(0 is 48 in ASCII)
Here's one way:
>> cellfun(#str2num, cellstr(s'))'
ans =
0 1 1
As you've noticed, MATLAB isn't that great for string manipulation. :)
You can as well do that:
x=3;
binNumber = dec2bin(x,3);
A=sprintf('%s',binNumber) - '0';