Input mask difference between 9999 and 9{4} - validation

I need two types of values xxxxx or xxxxx-xxxx where x is a digit to fit under the mask.
Why is the mask '0{5}-9{4}' correct when entering xxxxx, but the mask '00000-9999' is not?

Related

How to filter out the background in an RGB image(Matlab)? [duplicate]

I have converted my image into a mask and I would now like to obtain what the original colours were given this mask. I have an array called objectPixels that determines which locations belong to the object I am segmenting out. I have tried the code below but I am not obtaining the original colours.
What am I doing wring?
mask = false(size(grayImage));
mask(objectPixels) = true;
%on R channel
tmp = originalImage(:,:,1);
If I understand your question properly, you have a mask of pixels that belong to some objects. You now wish to find an image where any pixels that are labeled true will provide the original colour at these locations while false we skip. I'm going to assume that the output pixels are black if the mask locations are false. This can easily be computed using bsxfun with times as the function. We would essentially replicate the mask for each colour channel in your image, then multiply the mask with the original image.
As such:
out = bsxfun(#times, originalImage, cast(mask, class(originalImage)));
mask is originally a logical array, and in order to multiply both the mask and your original image together, they must be the same type, and that's why cast is used so that we can cast the image to the same type as the original image. We use class to determine the class or type of the original image.
As an example, let's use the onion.png image that's part of MATLAB's system path. I'm going to convert this image to grayscale using rgb2gray then choose an arbitrary threshold of graylevel 100 to give us a mask. Anything greater than 100 will give a mask value of true, while anything else is set to false.
Once I generate this mask, let's figure out what the original colours were based on these mask values. As such:
originalImage = imread('onion.png');
mask = rgb2gray(originalImage) >= 100;
out = bsxfun(#times, originalImage, cast(mask, class(originalImage)));
%// Show the images now
figure;
subplot(1,3,1);
imshow(im);
title('Original Image');
subplot(1,3,2);
imshow(mask);
title('Mask');
subplot(1,3,3);
imshow(out);
title('Output Image');
With the above code, I implement the logic I was talking about, with an additional figure that shows the original image, the mask generated as well as the output image that shows you the original colours of where the mask locations were true.
This is what I get:

Given a mask, how do I get obtain the original colors of an image?

I have converted my image into a mask and I would now like to obtain what the original colours were given this mask. I have an array called objectPixels that determines which locations belong to the object I am segmenting out. I have tried the code below but I am not obtaining the original colours.
What am I doing wring?
mask = false(size(grayImage));
mask(objectPixels) = true;
%on R channel
tmp = originalImage(:,:,1);
If I understand your question properly, you have a mask of pixels that belong to some objects. You now wish to find an image where any pixels that are labeled true will provide the original colour at these locations while false we skip. I'm going to assume that the output pixels are black if the mask locations are false. This can easily be computed using bsxfun with times as the function. We would essentially replicate the mask for each colour channel in your image, then multiply the mask with the original image.
As such:
out = bsxfun(#times, originalImage, cast(mask, class(originalImage)));
mask is originally a logical array, and in order to multiply both the mask and your original image together, they must be the same type, and that's why cast is used so that we can cast the image to the same type as the original image. We use class to determine the class or type of the original image.
As an example, let's use the onion.png image that's part of MATLAB's system path. I'm going to convert this image to grayscale using rgb2gray then choose an arbitrary threshold of graylevel 100 to give us a mask. Anything greater than 100 will give a mask value of true, while anything else is set to false.
Once I generate this mask, let's figure out what the original colours were based on these mask values. As such:
originalImage = imread('onion.png');
mask = rgb2gray(originalImage) >= 100;
out = bsxfun(#times, originalImage, cast(mask, class(originalImage)));
%// Show the images now
figure;
subplot(1,3,1);
imshow(im);
title('Original Image');
subplot(1,3,2);
imshow(mask);
title('Mask');
subplot(1,3,3);
imshow(out);
title('Output Image');
With the above code, I implement the logic I was talking about, with an additional figure that shows the original image, the mask generated as well as the output image that shows you the original colours of where the mask locations were true.
This is what I get:

How to add a Gaussian shaped object to an image?

I am interested in adding a single Gaussian shaped object to an existing image, something like in the attached image. The base image that I would like to add the object to is 8-bit unsigned with values ranging from 0-255. The bright object in the attached image is actually a tree represented by normalized difference vegetation index (NDVI) data. The attached script is what I have have so far. How can I add a a Gaussian shaped abject (i.e. a tree) with values ranging from 110-155 to an existing NDVI image?
Sample data available here which can be used with this script to calculate NDVI
file = 'F:\path\to\fourband\image.tif';
[I R] = geotiffread(file);
outputdir = 'F:\path\to\output\directory\'
%% Make NDVI calculations
NIR = im2single(I(:,:,4));
red = im2single(I(:,:,1));
ndvi = (NIR - red) ./ (NIR + red);
ndvi = double(ndvi);
%% Stretch NDVI to 0-255 and convert to 8-bit unsigned integer
ndvi = floor((ndvi + 1) * 128); % [-1 1] -> [0 256]
ndvi(ndvi < 0) = 0; % not really necessary, just in case & for symmetry
ndvi(ndvi > 255) = 255; % in case the original value was exactly 1
ndvi = uint8(ndvi); % change data type from double to uint8
%% Need to add a random tree in the image here
%% Write to geotiff
tiffdata = geotiffinfo(file);
outfilename = [outputdir 'ndvi_' '.tif'];
geotiffwrite(outfilename, ndvi, R, 'GeoKeyDirectoryTag', tiffdata.GeoTIFFTags.GeoKeyDirectoryTag)
Your post is asking how to do three things:
How do we generate a Gaussian shaped object?
How can we do this so that the values range between 110 - 155?
How do we place this in our image?
Let's answer each one separately, where the order of each question builds on the knowledge from the previous questions.
How do we generate a Gaussian shaped object?
You can use fspecial from the Image Processing Toolbox to generate a Gaussian for you:
mask = fspecial('gaussian', hsize, sigma);
hsize specifies the size of your Gaussian. You have not specified it here in your question, so I'm assuming you will want to play around with this yourself. This will produce a hsize x hsize Gaussian matrix. sigma is the standard deviation of your Gaussian distribution. Again, you have also not specified what this is. sigma and hsize go hand-in-hand. Referring to my previous post on how to determine sigma, it is generally a good rule to set the standard deviation of your mask to be set to the 3-sigma rule. As such, once you set hsize, you can calculate sigma to be:
sigma = (hsize-1) / 6;
As such, figure out what hsize is, then calculate your sigma. After, invoke fspecial like I did above. It's generally a good idea to make hsize an odd integer. The reason why is because when we finally place this in your image, the syntax to do this will allow your mask to be symmetrically placed. I'll talk about this when we get to the last question.
How can we do this so that the values range between 110 - 155?
We can do this by adjusting the values within mask so that the minimum is 110 while the maximum is 155. This can be done by:
%// Adjust so that values are between 0 and 1
maskAdjust = (mask - min(mask(:))) / (max(mask(:)) - min(mask(:)));
%//Scale by 45 so the range goes between 0 and 45
%//Cast to uint8 to make this compatible for your image
maskAdjust = uint8(45*maskAdjust);
%// Add 110 to every value to range goes between 110 - 155
maskAdjust = maskAdjust + 110;
In general, if you want to adjust the values within your Gaussian mask so that it goes from [a,b], you would normalize between 0 and 1 first, then do:
maskAdjust = uint8((b-a)*maskAdjust) + a;
You'll notice that we cast this mask to uint8. The reason we do this is to make the mask compatible to be placed in your image.
How do we place this in our image?
All you have to do is figure out the row and column you would like the centre of the Gaussian mask to be placed. Let's assume these variables are stored in row and col. As such, assuming you want to place this in ndvi, all you have to do is the following:
hsizeHalf = floor(hsize/2); %// hsize being odd is important
%// Place Gaussian shape in our image
ndvi(row - hsizeHalf : row + hsizeHalf, col - hsizeHalf : col + hsizeHalf) = maskAdjust;
The reason why hsize should be odd is to allow an even placement of the shape in the image. For example, if the mask size is 5 x 5, then the above syntax for ndvi simplifies to:
ndvi(row-2:row+2, col-2:col+2) = maskAdjust;
From the centre of the mask, it stretches 2 rows above and 2 rows below. The columns stretch from 2 columns to the left to 2 columns to the right. If the mask size was even, then we would have an ambiguous choice on how we should place the mask. If the mask size was 4 x 4 as an example, should we choose the second row, or third row as the centre axis? As such, to simplify things, make sure that the size of your mask is odd, or mod(hsize,2) == 1.
This should hopefully and adequately answer your questions. Good luck!

Extracting hidden image in matlab using least significant bit

So I'm trying to solve this problem but its been giving me what I think isn't the correct answer. Since every time i tried it would give me a new image.
Here is the problem:
Here is the image they provided us in BMP format (link for BMP download):
And here's what I've tried, or have been trying with no result so far:
So I made the entire 512x512 matrix a single vector so that i can extract the LSB from each pixel and then regroup every 8 into 1.
var1 is the vector form of the cdata matrix containing values from 0 to 255.
var2 is the least significant bit of each number, obtained by applying the modulus/remainder function by the division by 2.
var3 groups every 8 cells into 1 row and forms a matrix of (171^2)*8
var4 converts the matrix into a String array of characters
var5 converts each row in the string array into its corresponding number from binary to decimal
final puts it back into a 171*171 matrix.
imshow displays the data as an image, (I can also do imshow(final,colormap) but it won't change the picture much)
I'm suppose to get a recognizable picture, can anyone tell me what I'm doing wrong? I've looked all around the web for another way to do this with no luck. So stackoverflow was my last option.
EDIT: Here's the code
uiopen('D:\Users\Desktop\rally\question1.bmp',1) %gives cdata array (512*512) and colormap array (256*3)
var1 = cdata( : );
var2 = rem(var1,2);
var2 = var2(121:233928+120);
var3 = vec2mat(var2',8);
var4 = num2str(var3);
var5 = bin2dec(var4);
final = vec2mat(var5,171);
imshow(final)
After some heavy reverse engineering I was able to liberate a 171 x 171 grayscale version of Lena from your BMP. However, the description you were given is wrong in several respects, and unclear in others.
– The original image data have to be used sequentially, but not in Matlab's column-by-column way but in the normal image bitmap storage format, row-by-row. We therefore need a transpose:
A = imread('question1.bmp');
A = A';
– Data amounting to 120 pixels have to be skipped, but not from the beginning of the original image. We rather need to decode the least significant bits of all pixels, packing them into 8-bit bytes where the most significant bit is the first:
bits = rem(A, 2);
bits = reshape(bits, 8, []);
bytes = 2 .^ fliplr(0 : 7) * single(bits);
– Weirdly, the resulting byte sequence is organized in chunks of 64 bytes length:
data = reshape(bytes, 64, 512);
– The resulting matrix turns out to be organized in reversed column-row-order (we need to transpose again), and from the resulting sequence we need to skip 15 pixels (corresponding to 120 bits) at the beginning, and reshape to 171 x 171:
data = data';
I = reshape(data(16 : 171 * 171 + 15), 171, 171)';
Interestingly, the 15 bytes to be skipped contain the ASCII test "messageStart " followed by two bytes with values 171 and 171.
– With this, a familiar face is recovered:
imagesc(I)
axis image
colormap gray
Don't ask me how I figured this out, just give me the up-votes! ;-)
(Hint: looking at autocorrelation functions helped…)

binary or contiuous image?

I have an image which I want to use it in MATLAB. But, I am looking for a method by which I be able to automatically find that my image is binary (0 and 1) or continuous. Is there any solution of piece of code?
For starters you cannot formally talk about binary or continuous images. Digital images have a discrete set of values, taken from a finite value set depending on their format and pixel bit-wise representation.
For example a "binary" image would have 2 levels of gray (white and black), represented by 0 or 1 or any other combination of values, e.g. an image of levels 0, 255 is still "binary". A grayscale image for an 8-bit representation (i.e. 8 bits per pixel) will have 2^8 discrete levels of intensity from min 0 (black) to max 255 (white).
Thus you can test for the number of unique levels of gray, i.e. unique values in your input image:
I = imread(image_filename);
if length(unique(I))==2,
flag_binary = true
end
Examples:
I = imread('cameraman.tif');
>> disp(flag_binary)
0
I = imread('circles.png');
>> disp(flag_binary)
1
From your question I'm guessing you are dealing only with images of the logical or double class. The first should be used for real binary images but unfortunately, that's not always the case when using code out in the wild.
It seems to me your problem is to distinguish between a real image of double class (all values between 0 and 1) or a binary image as class double (all values are 0 or 1). The best way to do it is the following which returns true if the image only has the values 1 and 0:
bool = all ((image(:) == 1) + (image(:) == 0));
This is a line from isbw() in Octave image package where you can use isbw (img, "non-logical")
Calculate the histogram using imhist. If there are more than two distinct grayvalues in the histogram your image is not binary.

Resources