Is there a way if I want to apply medfilt2 function to the specific pixel locations rather than the whole image? The pixel locations can be represented using a binary image called IMask.
The lazy method is to just apply medfilt2 on the whole image and then copy the specific locations. E.g.
A = magic(10); % sample matrix
IMask = logical(randi([0 1],10)); % sample locations
B = medfilt2(A);
A(IMask) = B(IMask);
Not very elegant, but will do the job unless your matrix is gigantic and IMask is mostly false.
I do not see the point but if you define the matrix you are passing to medfilt2 is a subset of your image that you want being processed but you have to take care of the padding (zeros/symmetric/etc values at the boundaries).
Afterwards, you just have to replace the processed matrix within the image at the right position.
Related
I need to combine several images (of different textures) together. I have tried the following code:
% Read 4d data
I1 = importdata('Img1.tif');
I2 = importdata('Img2.tif');
% Extract a slice of the data
extractImg1 = I1(:,:,1);
extractImg2 = I2(:,:,1);
% compute image size
[ny1, nx1] = size(extractA1);
[ny2, nx2] = size(extractA2);
P1 = extractImg1 (round(ny1/2)-120:round(ny1/2)+120, round(nx1/2)-120:round(nx1/2)+120);
figure, imshow(P1); title('Img1');
P2 = extractImg2 (round(ny2/2)-120:round(ny2/2)+120, round(nx2/2)-120:round(nx2/2)+120);
figure, imshow(P2); title('Img2');
Please, what should I do next?
Secondly, the combined image will be needed for laser printing. The images do not have exactly the same pixel dimensions thus; I was told that it would not make sense to combine them, as this might slightly reduce accuracy.
Nonetheless, I still have a feeling that combining the images wouldn’t be wrong considering that they all have the same resolutions.
I need advice as to whether I should go ahead with the combination. Many thanks in advance.
You have extracted two equal-sized regions from the two images. If you want to put those side-by-side in the same image, use cat, or equivalently, use the square brackets []:
next_to_each_other = [P1,P2];
on_top_of_each_other = [P1;P2];
But note that you can put these things together even if they don't have the same sizes. For example, if I1 is NxM pixels, and I2 is NxK (with N the vertical size as customary in MATLAB) then you can still do [I1,I2] because the vertical size matches.
If nether the vertical nor horizontal sizes match, you can pad one with zeros (or whatever value is appropriate) using padarray before putting them together:
ny1 = size(I1,1);
ny2 = size(I2,1);
if ny1<ny2
I1 = padarray(I1,[ny2-ny1,0,0],0,'post'); % The 0 is the value to pad
elseif ny2<ny1
I2 = padarray(I2,[ny1-ny2,0,0],0,'post'); % The 0 is the value to pad
end
out = [I1,I2];
padarray also allows replicating the data in the matrix instead of padding with zeros. Read the documentation to find what is appropriate. padarray requires the Image Processing Toolbox. If you don't have it, you can replicate its functionality by creating an array with zeros of the appropriate size using the zeros function, and adding it to the image using something like [I1;zeros(ny2-ny1,size(I1,2),size(I1,3)].
For a university assignment I have to take an image of size 512x512 and then apply an effect to particular blocks of the image, as displayed in the image below.
I have managed to achieve this by accessing particular regions of the image using indexing, like this:
w1_region = [DCTImage(1:imageSizeQuarter, imageSizeQuarter+1:imageSizeHalf)];
This is repeated for w2 and w3. These regions are all of size 128x128 and need to be written back into the original image.
However now what I need to do is overwrite the blocks of the original image with the edited blocks, so that I have a full image with 3 blocks w1, w2, w3 that have been modified.
How can I go about overwriting the matrix that defines the original image with the modified blocks? Is there a way that I can effectively say "Overwrite the values held in the matrix starting at X"?
I feel like there is some kind of matrix operation that would allow me to do this but I'm not entirely sure which.
You can use for example:
BlockFunc = #(block_struct) YourFunction(block_struct);
block_size = [128 128];
block_edges = blockproc(file_name,block_size,BlockFunc);
You should just create a function with Name of YourFunction. The input of this function is block_struct and you can access to your block position and its data.
Moreover you can use global variable to handle between YourFunction and your main script.
I have a segmented image. I wish to extract the middle pixel(s) of each segmentation. The goal is to extract the mean color from the middle pixel.
The following diagram illustrates what I mean by 'middle pixel':
The alternative middle pixels are also acceptable.
What algorithms/functions are available in Matlab to achieve something similar to this? Thanks.
If I'm understanding what you want correctly, you're looking for the centroid. MATLAB has the regionprops function which measures the properties of separate binary objects as long as the objects.
You can use the Centroid property. Assuming your image is stored in im and is binary, something like this will do:
out = regionprops(im, 'Centroid');
The output will be a structure array of N elements where N corresponds to the total number of objects found in the image. To access the ith object's centroid, simply do:
cen = out(i).Centroid;
If you wish to collect all centroids and place them perhaps in a N x 2 numeric array, something like this would work:
out = reshape([out.Centroid], 2, []).';
Each row would be the centroid of an object found in the image. Take note that an object is considered to be a blob of white pixels that are connected to each other.
I have an image that was read in using the imread function. My goal is to collect pairs of pixels in an image in MATLAB. Specifically, I have read a paper, and I am trying to recreate the following scenario:
First, the original image is grouped into pairs of pixel values. A pair consists of two neighboring pixel values or two with a small difference value. The pairing could be done horizontally by pairing the pixels on the same row and consecutive columns, or vertically, or by a key-based specific pattern. The pairing could be through all pixels of the image or just a portion of it.
I am looking to recreate the horizontal pairing scenario. I'm not quite sure how I would do this in MATLAB.
Assuming your image is grayscale, we can easily generate a 2D grid of co-ordinates using ndgrid. We can use these to create one grid, then shift the horizontal co-ordinates to the right to make another grid and then use sub2ind to convert the 2D grid into linear indices. We can finally use these linear indices to create our pixel pairings that you have described in your comments (you should really add that to your post BTW). What's important is that you need to skip over every other column in a row to ensure unique pixel pairings.
I'm also going to assume that your image is grayscale. If we go to colour, this will be slightly more complicated, and I'll leave that to you as a learning exercise. Therefore, assuming your image was read in through imread and is stored in im, do something like this:
[rows,cols] = size(im);
[X,Y] = ndgrid(1:rows,1:2:cols);
ind = sub2ind(size(im), X, Y);
ind_shift = sub2ind(size(im), X, Y+1);
pixels1 = im(ind);
pixels2 = im(ind_shift);
pixels = [pixels1(:) pixels2(:)];
pixels will be a 2D array, where each row gives you the pixel intensities of a particular pairing in the image. Bear in mind that I processed each row independently. As such, as soon as we are done with one row, we simply move on to the next row and continue the procedure. This also assumes that your image has an even number of columns. Should it not, you have a decision to make. You need to either pad the image with one column at the end, and this column can be anything you want, or you can remove this column from the image before processing. If you want to fill in this column, you can either make it all zeroes, or perhaps replicate the last column and place this beside the last column in the original image. Therefore, an appropriate pre-processing step may look something like this:
if mod(cols,2) ~= 0
im = im(:,1:end-1);
end
The above code simply removes the last column in the image if the number of columns is odd. Once you run through this code, you can run the first bit of code that I had above.
Good luck!
I would like to crop an image but I want to retain the part of image that is outside of the rectangle. How can this can be done?
It seems that with imcrop only the part within the rectangle can be retained.
An image in Matlab is represented by a matrix, just like any other matrix, you can read more about representation forms here.
It seems that what you want to do is to take the area that you don't want and change the values of the corresponding cells in the matrix to the color that you want to put instead (each cell in the matrix is a pixel in the image). That is if you know the place where your unwanted data is.
If you don't know where it is, and want to use the tool given by imcrop to manually choose the "cropped" area, you can take the resulting matrix, and find the part of the original image which is an exact match with the cropped part, and to color it as you wish.
The code for doing this:
I=imread('img_9.tif');
I2=imcrop(I,[60,50,85,85]);
n_big=size(I);
n_small=size(I2);
for j1=1:(n_big(1)-n_small(1))
for j2=1:(n_big(2)-n_small(2))
Itest=I(j1:j1+n_small(1)-1,j2:j2+n_small(2)-1,:);
if ( Itest == I2)
I(j1:j1+n_small(1)-1,j2:j2+n_small(2)-1,:) = zeros(n_small(1),n_small(2),3);
end
end
end
figure(1);
imshow(I);
figure(2);
imshow(I2);
The results of my test were:
original:
cropped:
resulting image:
maybe what you want to do is first a mask with the inverse area of what you want to crop and save this result.