MATLAB crop image and make more blue not displaying change - image

In Matlab, I am trying to crop an image and be able to manipulate in some way (I adjusted contrast) and show change in formatting as its displayed beside the original image (by making it turn more and more blue).
The code runs successfully, but it seems to already have made the cropped image as blue as the for loop would take it.
How can I edit the code so that as the original is displayed beside the cropped, the cropped image is showing the change in formatting of turning more and more blue?
Here's what I have so far:
I = imread('peppers.png');
I2 = imcrop(I);
I3 = imadjust(I2,[.2 .3 0; .6 .7 1],[]);
subplot(1,2,1), subimage(I);
for i = 1:0.1:7
I3(:,:,3) = I3(:,:,3) + i;
subplot(1,2,2), subimage(I3)
end
To understand what is meant by showing an image to turn more and more blue upon display, please run:
img = imread('peppers.png');
for i = 1:0.1:7
figure(1)
img(:,:,3) = img(:,:,3) + i;
imshow(img)
end

If I understand what you want correctly, you want to display the original image on the left, and the bluer image on the right, and showing it progressively going blue as the loop is iterating. What I suggest you do is pause at each iteration in the loop to give you time to see the results. You can also put a title that shows what value i is at each iteration before the image changes. Also, make sure you add a drawnow command before you pause to flush the buffer so that you can visualize the results immediately. In other words, try this:
I = imread('peppers.png');
I2 = imcrop(I);
I3 = imadjust(I,[.2 .3 0; .6 .7 1],[]);
figure;
subplot(1,2,1);
subimage(I);
for i = 1:0.1:7
I3(:,:,3) = I3(:,:,3) + i;
subplot(1,2,2);
subimage(I3);
title(num2str(i)); %// Change - add title
drawnow; %// Change - flush buffer
pause(0.3); %// Change - add a pause
end
You should see the change in the blue channel for each value of i every 0.3 seconds. Change the value of 0.3 according to your tastes. BTW, the image is uint8, so adding floating point values to the blue channel will have no effect as these values will be truncated. Only integer values will show something appreciable.

Related

How do I save just figure image without any graduation and numbers on x, y axis?

I used matlab code.
img = imread('cmap3.png')
map = jet(256)
ind = rgb2ind(img,map)
colormap(map)
cm = colormap('gray)
image(ind)
Through above code, I got the .
I want to save just the gray scale image without any graduations and numbers on x,y axis.
How do I remove them and save gray scale image?
If you use imwrite, you won't save the axes' labels.
For actual plots, there exists a different solutions, eg. described here: set the axis to start at the very left bottom corner so that there is no space left for descriptions: set(gca, 'Position',[0 0 1 1]). Than you can even use print to save the image/figure.

Matlab picture intensity level adjustment

I have a specific question to ask about the intensity adjustment for image processing. I need high constraint value to find small gaps in the image which is shown as a red circle in the image. I used a manual threshold value 0.99 to convert the grayscale image to binary image for other processing methods. However, as the illumination on the surface did not distribute evenly, some parts of the image is lost. I used the adaptive method suggested by Matlab, however, the results is similar to a global threshold graythresh.
I will show my code and result below.
I0 = imread('1_2.jpg');
[R,C,K] = size(I0);
if K==1
I1 = I0;
else
I1 = rgb2gray(I0);
end
%Adjsut image to get a standar binary picture
%Adjust image intensity value
I1 = imadjust(I1,[0.1 0.7],[]);
BW0 = im2bw(I1,0.99);
figure;
BW0 = bwareaopen(BW0,10000);
%Fill non_crack hole error
BW0 = bwareaopen(1-BW0,500);
BW0 = 1-BW0;
imshow(BW0);
After this process, only half of the image will be left. I want a whole image, with locally intensity threshold but show the same feature as the high-level threshold. What can I do?
Thanks
Try adaptthresh:
I0 = imread('1_2.jpg');
[R,C,K] = size(I0);
if K==1
I1 = I0;
else
I1 = rgb2gray(I0);
end
T = adaptthresh(I1, 0.4); %adaptive thresholding
% Convert image to binary image, specifying the threshold value.
BW = imbinarize(I1,T);
% Display the original image with the binary version, side-by-side.
figure
imshowpair(I1, BW, 'montage')

Display an image scale space in MATLAB

I have 8 images and I want to show them in a scale-space format shown below. The original image height and width is 256. Then on right side of original image, at every level the size is reduced by 2. Like here, image height and width is 256. On the right side of original image, height and width is 128, 64, 32, 16, 8, 4 , 2.
I have all the images in their respective dimensions. I just want to know how do I arrange the images according the pattern shown below. Thanks in advance.
This looks like you are trying to build a scale-space and displaying the results to the user. This isn't a problem to do. Bear in mind that you will have to do this with for loops, as I don't see how you will be able to do this unless you copy and paste several lines of code. Actually, I'm going to use a while loop, and I'll tell you why soon.
In any case, you need to declare an output image that has as many rows as the original image, but the columns will be 1.5 times the original image to accommodate for the images on the right.
First, write code that places the original image on the left side, and the version that is half the size on the right. Once you do this, you write a for loop, use indexing to place the images in the right spots until you run out of scales, and you need to keep track of where the next image starts and next image ends. Bear in mind that the origin of where to write the next images after the first subsampled one will start at the column location of the original image, and the row is right where the previous one ends. As an example, let's use the cameraman.tif image that is exactly 256 x 256, but I will write code so that it fits any image resolution you want. When I subsample the image, I will use imresize in MATLAB to help with the resizing of the image, and I'll specify a sampling factor of 0.5 to denote the subsampling by 2. The reason why I would use a while loop instead, is because we can keep looping and resizing until one of the dimensions of the resized image is 1. When this is the case, there are no more scales to process, and so we can exit.
As such:
%// Read in image and get dimensions
im = imread('cameraman.tif');
[rows,cols] = size(im);
%// Declare output image
out = zeros(rows, round(1.5*cols), 'uint8');
out(:,1:cols) = im; %// Place original image to the left
%// Find first subsampled image, then place in output image
im_resize = imresize(im, 0.5, 'bilinear');
[rows_resize, cols_resize] = size(im_resize);
out(1:rows_resize,cols+1:cols+cols_resize) = im_resize;
%// Keep track of the next row we need to write at
rows_counter = rows_resize + 1;
%// For the rest of the scales...
while (true)
%// Resize the image
im_resize = imresize(im_resize, 0.5, 'bilinear');
%// Get the dimensions
[rows_resize, cols_resize] = size(im_resize);
%// Write to the output
out(rows_counter:rows_counter+rows_resize-1, cols+1:cols+cols_resize) = ...
im_resize;
%// Move row counter over for writing the next image
rows_counter = rows_counter + rows_resize;
%// If either dimension gives us 1, there are no more scales
%// to process, so exit.
if rows_resize == 1 || cols_resize == 1
break;
end
end
%// Show the image
figure;
imshow(out);
This is the image I get:

How to process a "Very Large image file" in MATLAB and find out the pixel with largest value

I have to process a very large image ( say 10 MB image file or even more).I have to remove artifacts and dead pixels in MATLAB
I have read about Block Processing of Large Images, but have no idea how to apply it to a 16 bit image.
I am referring to removal of pixels which have highest value into the average value of surrounding pixel .my code is not working on my image which is 80 MB of size
numIterations = 30;
avgPrecisionSize = 16; % smaller is better, but takes longer
% Read in the image grayscale:
originalImage = double(rgb2gray(imread('C:\Documents and Settings\admin\Desktop\TM\image5.tif')));
% get the bad pixels where = 0 and dilate to make sure they get everything:
badPixels = (originalImage == 0);
badPixels = imdilate(badPixels, ones(12));
%# Create a big gaussian and an averaging kernel to use:
G = fspecial('gaussian',[1 1]*100,50);
H = fspecial('average', [1,1]*avgPrecisionSize);
%# User a big filter to get started:
newImage = imfilter(originalImage,G,'same');
newImage(~badPixels) = originalImage(~badPixels);
% Now average to
for count = 1:numIterations
newImage = imfilter(newImage, H, 'same');
newImage(~badPixels) = originalImage(~badPixels);
end
%% Plot the results
figure(123);
clf;
% Display the mask:
subplot(1,2,1);
imagesc(badPixels);
axis image
title('Region Of the Bad Pixels');
% Display the result:
subplot(1,2,2);
imagesc(newImage);
axis image
set(gca,'clim', [0 255])
title('Infilled Image');
colormap gray
newImage2 = roifill(originalImage, badPixels);
figure(44);
clf;
imagesc(newImage2);
colormap gray
You are doing a few things which are obvious problems (but it might depend specifically on how far you can get into the code before you run out of memory)
1) You are immediately converting the whole image to double
2) You are identifying certain pixels which you want to replace, but passing the whole image to imfilter and then throwing away (presumably) most of the output:
newImage = imfilter(originalImage,G,'same'); % filter across the entire image
newImage(~badPixels) = originalImage(~badPixels); % replace all the good pixels!
Without converting to double, why not first check where the bad pixels are, do your processing on subregions of the appropriate size around those pixels (the subregions can be converted to double and back), and then reassemble the image at the end?
blockproc may work if you can write your filtering option as a function which takes in an image area and returns the correct area - you'll have to use the border_size option appropriately and make sure your function just returns the original image without bothering to do any filtering if it hits a block with no bad pixels in. You can even have it write out to file as well.

Counting the squama of lizards

A biologist friend of mine asked me if I could help him make a program to count the squama (is this the right translation?) of lizards.
He sent me some images and I tried some things on Matlab. For some images it's much harder than other, for example when there are darker(black) regions. At least with my method. I'm sure I can get some useful help here. How should I improve this? Have I taken the right approach?
These are some of the images.
I got the best results by following Image Processing and Counting using MATLAB. It's basically turning the image into Black and white and then threshold it. But I did add a bit of erosion.
Here's the code:
img0=imread('C:...\pic.png');
img1=rgb2gray(img0);
%The output image BW replaces all pixels in the input image with luminance greater than level with the value 1 (white) and replaces all other pixels with the value 0 (black). Specify level in the range [0,1].
img2=im2bw(img1,0.65);%(img1,graythresh(img1));
imshow(img2)
figure;
%erode
se = strel('line',6,0);
img2 = imerode(img2,se);
se = strel('line',6,90);
img2 = imerode(img2,se);
imshow(img2)
figure;
imshow(img1, 'InitialMag', 'fit')
% Make a truecolor all-green image. I use this later to overlay it on top of the original image to show which elements were counted (with green)
green = cat(3, zeros(size(img1)),ones(size(img1)), zeros(size(img1)));
hold on
h = imshow(green);
hold off
%counts the elements now defined by black spots on the image
[B,L,N,A] = bwboundaries(img2);
%imshow(img2); hold on;
set(h, 'AlphaData', img2)
text(10,10,strcat('\color{green}Objects Found:',num2str(length(B))))
figure;
%this produces a new image showing each counted element and its count id on top of it.
imshow(img2); hold on;
colors=['b' 'g' 'r' 'c' 'm' 'y'];
for k=1:length(B),
boundary = B{k};
cidx = mod(k,length(colors))+1;
plot(boundary(:,2), boundary(:,1), colors(cidx),'LineWidth',2);
%randomize text position for better visibility
rndRow = ceil(length(boundary)/(mod(rand*k,7)+1));
col = boundary(rndRow,2); row = boundary(rndRow,1);
h = text(col+1, row-1, num2str(L(row,col)));
set(h,'Color',colors(cidx),'FontSize',14,'FontWeight','bold');
end
figure;
spy(A);
And these are some of the results. One the top-left corner you can see how many were counted.
Also, I think it's useful to have the counted elements marked in green so at least the user can know which ones have to be counted manually.
There is one route you should consider: watershed segmentation. Here is a quick and dirty example with your first image (it assumes you have the IP toolbox):
raw=rgb2gray(imread('lCeL8.jpg'));
Icomp = imcomplement(raw);
I3 = imhmin(Icomp,20);
L = watershed(I3);
%%
imagesc(L);
axis image
Result shown with a colormap:
You can then count the cells as follows:
count = numel(unique(L));
One of the advantages is that it can be directly fed to regionprops and give you all the nice details about the individual 'squama':
r=regionprops(L, 'All');
imshow(raw);
for k=2:numel(r)
if r(k).Area>100 % I chose 100 to filter out the objects with a small are.
rectangle('Position',r(k).BoundingBox, 'LineWidth',1, 'EdgeColor','b', 'Curvature', [1 1]);
end
end
Which you could use to monitor over/under segmentation:
Note: special thanks to #jucestain for helping with the proper access to the fields in the r structure here

Resources