Could I use dct to extract the feature of .png images?
Or dct is just for jgp? Because my dataset using png format.
I've read several journals, and find that 2d dct could used to extract the feature based on coefficient. I need the features for Neural Neutwork.
I've tried basic code to do 2d dct (using matlab):
i = imread ('AB1.png');
b = im2double (x);
d = dct2 (b, [64 64]);
but, i am still not sure, that this code really give me the appropriate feature that i need. do you have any recommendation of another codes?
And also why 'dctmtx' function give me the same coefficient for different image?
*Thanks before.
First, png does not matter, as long as you are not doing some alpha channel processing etc, reading png is just like reading jpg since you are doing your DCT on the matrix representation of the image - instead of the file.
Your code:
d = dct2 (b, [64 64]);
should give you the 2d-DCT of the zero padded 64 by 64 image.
To check you could try something like:
d = dct(dct(b.').') %//If you want to pad your image with zero first.
since dct2 is implemented using dct at core.
as for dctmtx - it should give you the dct matrix which you can apply to your image matrix to obtain the dct result of your image (Thus , the result generated by dctmtx should be the same for any image that are the same size). Matlab gives a clear example:
A = im2double(imread('rice.png')); %//your image
D = dctmtx(size(A,1)); %//Generate a DCT matrix of the SIZE of your image
dct = D*A*D'; %//Obtain 2D - DCT
figure, imshow(dct) %//Result transform
All three examples should give you the same result.
And finally, in terms of best feature extraction algorithm/transformation, it really depends on what you are trying to achieve - recognition/enhancement/encryption but in general, DCT is very good and efficient for regular images.
Related
I am trying to convert the rgb image into a grayscale and then cluster it using kmean function of matlab .
here is my code
he = imread('tumor2.jpg');
%convert into a grayscale image
ab=rgb2gray(he);
nrows = size(ab,1);
ncols = size(ab,2);
%convert the image into a column vector
ab = reshape(ab,nrows*ncols,1);
%nColors=no of clusters
nColors = 3;
%cluster_idx is a n x 1 vector where cluster_idx(i) is the index of cluster assigned to ith pixel
[cluster_idx, cluster_center ,cluster_sum] = kmeans(ab,nColors,'distance','sqEuclidean','Replicates',1,'EmptyAction','drop' );
figure;
%converting vector into a matrix of dimensions equal to that of original
%image dimensions (nrows x ncols)
pixel_labels = reshape(cluster_idx,nrows,ncols);
pixel_labels
imshow(pixel_labels,[]), title('image labeled by cluster index');
problems
1) output image is always a plain white image.
i tried the solution given in the link below but output of the image is a plain gray image in this case.
find the solution tried here
2) when i execute my code second time ,execution does not proceed beyond k-mean function (it is likes an infinite loop there). hence no output in this case.
Actually, it looks like when you are colour segmenting kmeans is known to fall in local minima. This means that often, it wont find the amount of clusters you want as the minimization is not the best (that's why lots of people use other type of segmentation, such as level sets or simple region growing).
An option is to increase the amount of Replicates (amount of times kmeans will try to find the answer). At the moment you are setting it to 1, but you could try 3 or 4, and it may reach the solution that way.
In this question the accepted answer recommends to use a kmeans version of the algorithm specifically created for image segmentation. I havent tried myself but I think its worth a shot.
Link to FEX
I am trying to use the functions provided in the Matlab Wavelet Toolbox to create a multi-level discrete wavelet decomposition of an image, extracting the coefficients, manipulating them, and recomposing them back into the image.
I tried using a number of functions but none of them seem to do what I need. These are the steps to do this.
Use wavedec2 to decompose the image into [C,S].
[C,S] = wavedec2(X,N,Lo_D,Hi_D)
I then must use detcoef2 to extract the detail coefficients from [C,S]. [C,S] is the 'wavelet decomposition structure', it does not represent the actual coefficients such as cD, cH, cV.
[H,V,D] = detcoef2('all',C,S,N)
Manipulate the data
Reconstruct [C,S] ???? no function does this.
Use waverec2 to recompose the original image.
X = waverec2(C,S,Lo_R,Hi_R)
The problem is with step 4. There is no function that recreates the [C,S] and I can't call the function waverec2 because it needs the manipulated version of C and S.
Do I not need wavedec2 and waverec2? Perhaps should I just use detcoef2 and upcoef2?
Someone with some experience with DWT could solve this in a minute, I am fairly new to it.
Thanks
I'm curious as to why you can't use dwt2 for computing the 2D DWT of images. What you have there is a lot more work than what you should be doing. dwt2 is much more suitable to do what you want. You'd call dwt2 like so:
[LL,LH,HL,HH] = dwt2(X,Lo_D,Hi_D);
X is your image, and Lo_D and Hi_D are your low-pass and high-pass filters you want to apply to the image. LL is the low-passed version of the image, where the horizontal and vertical directions are low-passed, LH is where the vertical direction is low-passed and the horizontal direction is high-passed, HL is the vertical direction is high-passed and the horizontal direction is low-passed, and HH is where both directions are high-passed. As such LH, HL and HH are the detail coefficients while LL contains the structure.
You can also specify the filter you want with a string as the second parameter:
[LL,LH,HL,HH] = dwt2(X,'wname');
'wname' is a string that specifies what filter you want. You can type in help wfilters to see what filters are available.
For example, by doing using cameraman.tif from MATLAB's system path, we can do a one level 2D DWT (using the Haar wavelet) and show all of the components like so:
im = imread('cameraman.tif');
[LL, LH, HL, HH] = dwt2(im2double(im), 'haar');
imshow([LL LH; HL HH], []);
I use im2double to convert the image to double precision to ensure accuracy. We get this image:
Note that the image is subsampled by 2 in order to produce the decompositions of LL, LH, HL and HH.
Once you have these components, you can certainly manipulate them to your heart's content. Once you manipulate them, you can simply use idwt2 like so:
Y = idwt2(LL,LH,HL,HH,Lo_R,Hi_R); %//or
Y = idwt2(LL,LH,HL,HH,'wname');
The four components are assumed to be double, and so you can convert the images back to whatever type that was representing the image. Assuming your image was uint8, you can do: Y = im2uint8(Y); to convert back.
This should hopefully be what you're looking for!
As a part of my project, initially find low resolution of the input image. Then as a second step i need find the noise in the low-resolution image. How to find noise in an image and its standard deviation using matlab?
You can use the std matlab function which returns the standard deviation of a matrix.
std_deviation = std(image);
This will give you the standard deviation of the whole image. However you cannot calculate the noise std since you don't have the original filtered image.
Possible solution: (Not accurate) : This suppose thaht your noise is gaussian
Well, you can render several Noise matrices and test them:
(choose your mean_vector and std_vector)
for i = 1 : length(mean_vector) % or length(std_vector)
Noise(:,:,i) = mean_vector(i) + std_vector(i).*randn(size(your_image))
% extracting the possibly filtered image
filtered_img(:,:,i) = your_image - Noise(:,:,i);
end
Then display every filtered_img and choose the one that looks the less noisy.
You can denoise the image, compute the difference between the raw image and the denoised version, and then compute the standard deviation of the difference.
For instance:
a=imread('input');
a=double(a);
b=imsharpen(a); %you may need to tune the parameters
diff=b-a;
noise=std2(diff);
You can find the variance of noise in the image assuming that you know the distribution. You will know this if you have read some of the great works in image denoising field by Donoho & John.
To find the noise std. dev. of noise in an image with Gaussian contamination (additive), you can use the Median Absolute Deviation (MAD) estimator on the derivative of the image using the following kernel:
I am writing the python code for this, you can easily write it in Matlab:
def find_stddevs(img):
k = np.asmatrix([[-1.0/9, -1.0/9 ,-1.0/9],
[-1.0/9, 8.0/9 , -1.0/9],
[-1.0/9, -1.0/9 ,-1.0/9]])
filtered = convolve(img,k,mode='reflect')
median_a = np.median(filtered)
stddev = np.median(np.absolute(filtered - median_a))/0.67449 #Gaussian noise assumption
return stddev
You can see the derivation and the logic Here on Wikipedia.
Again, most people think it can be done. This is true iff you do not have any prior about the type of contamination in the image.
The other day I asked about something similiar and finally i solved that part, but i am stuck again.
I would like to create a noise filter, to remove noise from an image, avoiding edges and boundaries. My imput is an image file, and the filter is a smoothing linear FIR.
BUT i want the result to be written to the output mixed with the original content, following the next equation:
result(x,y) = original(x,y)*mask(x,y) + filter_output(x,y)*(1-mask(x,y))
Where: original(x,y) would be the imput, the image with noise (this for example, with gaussian noise).
mask(x,y) is a matrix of coefficients based on the edges of the image (alredy done)
and filter_ouput(x,y), should be the image after the linear FIR.
My problem is: I tried with so many filters and types of noise (gaussian, salt&pepper...), and i don't get a good result. The result(x,y) i get is the same than the image with noise! With any change. So strange.
Which filter would be the correct? I don't know if my error is in the filter, or in the code. But something is being implemented wrong. Here is the code.
filter = ones(5,5) / 25;
a2 = imfilter(a,filter); % a is the image with noise, a2 is the filtered image (output)
%The equation. G is the mask.
result=uint8(a).*uint8(G) + uint8(a2).*uint8(1-G);
imshow(result);
PS: Original image without noise
Any idea? Thank you so much!
a2 is smooth after applying the averaging filter on a. I'm trying to understand what you are expecting to show in the result image. Actually your G , obtained after sobel operator, is also a uint8 image ranging from 0 to 255. So I guess your
result=uint8(a).*uint8(G) + uint8(a2).*uint8(1-G);
should be result=a.*uint8(G1) + a2.*uint8(1-G1); where G1 =im2bw(G,thresh) with your preset thresh value.
EDIT
Response to your suggestion: how about using
result=a2+(255-G);
I have a vein image as follow. I use watershed algorithm to extract the skeleton of the vein.
My code: (K is the original image).
level = graythresh(K);
BW = im2bw(K,level);
D = bwdist(~BW);
DL = watershed(D);
bgm = DL == 0;
imshow(bgm);
The result is:
As you can see lot of information is lost. Can anybody help me out? Thanks.
It looks like the lighting is somewhat uneven. This can be corrected using certain morphological operations. The basic idea is to compute an image that represents just the uneven lighting and subtract it, or to divide by it (which also enhances contrast). Because we want to find just the lighting, it is important to use a large enough structuring element, so that the operation examines more global properties rather than local ones.
%# Load image and convert to [0,1].
A = im2double(imread('http://i.stack.imgur.com/TQp1i.png'));
%# Any large (relative to objects) structuring element will do.
%# Try sizes up to about half of the image size.
se = strel('square',32);
%# Removes uneven lighting and enhances contrast.
B = imdivide(A,imclose(A,se));
%# Otsu's method works well now.
C = B > graythresh(B);
D = bwdist(~C);
DL = watershed(D);
imshow(DL==0);
Here are C (left), plus DL==0 (center) and its overlay on the original image:
You are losing information because when you apply im2bw, you are basically converting your uint8 image, where the pixel brightness takes a value from intmin('uint8')==0 to intmax('uint8')==255, into a binary image (where only logical values are used). This is what entails a loss of information that you observed.
If you display the image BW you will see that all the elements of K that had a value greater than the threshold level turn into ones, while those ones below the threshold turn into zeros.
Yes, you'll need to lower your threshold likely (lower than what Otsu's method is giving you). And if the edge map is noisy when you lower the threshold, you should apply a 2-D Gaussian smoothing filter before you lower the threshold. This will move the edges slightly but will clean up noise too, so it's a tradeoff.
The 2-D Gaussian can be applied doing something like
w=gausswin(N,Alpha) % you'll have to play with N and alpha
K = imfilter(K,w,'same','symmetric'); % something like these options
Before you apply the rest of your algorithm.