Octave; Plot Transformation Curve for Histogram Equalization - matlab

This question was migrated from Super User because it can be answered on Stack Overflow.
Migrated last month.
Matlab has this command:
[J,T] = histeq(I);
[___,T] = histeq(___) also returns the transformation T that maps the gray component of the input grayscale image
I use GNU Octave, version 6.4.0. But the histeq command of Octave does not have that output argument. How I can obtain the transformation of histeq and plot it in Octave?

The mapping T is given by the cdf of the normalized histogram (see Histogram equalization implementation).
This mapping is stored in the variable Icdf in histeq.m. Since the code for this function (aside from input checking) is only 6 lines, it would be a simple matter to clone the function to access T.

Related

Fit data to other formulations of Gumbel and Weibull models in Matlab

I need to fit Extreme Value distributions to wind speed data. I'm using Matlab for doing this. It may not be evident to a user that there are alternative formulations of the Gumbel and Weibull models than those that Matlab has built in in its commands: evfit and wblfit. Thus, the definitions implemented are:
Gumbel (suited for minima)
However, there's another version of the Gumbel to which I need to fit the data:
Weibull
Same comments applies to the Weibull models in Matlab. In previous versions, Matlab implemented a version of the Weibull in the command weibfit (not available anymore), which was later replaced by wblfit.
and previously as:
My question is: any ideas how can the data be fitted to the previous definitions of the Gumbel and Weibull models in Matlab?
Thanks,
You can estimate the parameter of a custom distribution using the function mle:
Example with your custom weibul PDF:
data = wblrnd(1,1,1000,1); %random weibull data
custompdf = #(x,a,b) (b*a).*x.^(b-1).*exp(-a*x.^b); %your custom PDF function
opt = statset('MaxIter',1e5,'MaxFunEvals',1e5,'FunValCheck','off'); %Iteration's option
[param,ci]= mle(data,'pdf',custompdf,'start',[1 1],'Options',opt,'LowerBound',[0 0],'UpperBound',[Inf Inf])
If the function doesn't converge, you can adjust the starting point with some better suited value.

Using cv.remap (mexopencv) instead of interp2 (MATLAB)

I am experimenting with the mexopencv project that allows using the
OpenCV library from MATLAB .m files in order to compare the performance
of the native MATLAB functions with the OpenCV functions
I would like to substitute a call to the MATLAB interp2 function:
Vq = interp2(X,Y,V,Xq,Yq) returns interpolated values of a function of two variables at specific query points using linear interpolation. The results always pass through the original sampling of the function. X and Y contain the coordinates of the sample points. V contains the corresponding function values at each sample point. Xq and Yq contain the coordinates of the query points.
The substitute shall be a call to the cv.remap function.
Applies a generic geometrical transformation to an image
dst = cv.remap(src, map1, map2)
dst = cv.remap(src, map1)
dst = cv.remap(..., 'OptionName',optionValue, ...)
The three SO questions Similar OpenCV Api for interp2 in Matlab,
How to do grid interpolation interp2 in OpenCV
and cv::remap (in opencv) and interp2 (matlab)
state that the OpenCV function remap can be used instead of the native MATLAB
function interp2, but I have no idea how-to correctly interpret/transform the
arguments (I have no experience regarding MATLAB and computer vision).
How can I use the mexopencv function cv.remap to get the same effect as if one
would call Vq = interp2(X,Y,V,Xq,Yq)?

Fitting a pdf to an histogram in matlab

I'm having troubles when fitting a pdf to an histogram in Matlab. I'm using gmdistribution.fit because my data is multi-modal. This is what I have done:
data=[0.35*randn(1,100000), 0.5*randn(1,100000)+5, 1*randn(1,100000)+3]'; %multimodal data
x=min(data):(max(data)-min(data))/10000:max(data);
%Normalized Histogram
[counts,edges]=histcounts(data,500, 'Normalization', 'pdf');
bw=edges(2)-edges(1);
centers=edges(1:end-1)+bw;
H = bar(centers,counts,'hist');
hold on
%Fitting with gmdistribution
rng default
obj=gmdistribution.fit(data,3,'Replicates',5);
%the PDF
PDF=zeros(1,length(x));
for i=1:obj.NumComponents
k=obj.ComponentProportion(i);
u=obj.mu(i);
sigma=obj.Sigma(i);
PDF=PDF+k*normpdf(x,u,sigma);
end
PDF=PDF/trapz(x,PDF); %normalization (just in case)
plot(x,PDF)
%Fitting with ksdensity (for comparison)
[PDF2,xi]=ksdensity(data,x);
plot(x,PDF2)
legend('Normalized Histogram','gmdistribution','ksdensity')
Histogram and PDFs
As you can see, the Gaussian Mixture doesn't fit the histogram properly. The PDF from the ksdensiti function is much better. I have also tried to fit just one gaussian. If you run the same previous code, using
data=[0.35*randn(1,100000)]';
and
obj=gmdistribution.fit(data,1,'Replicates',5);
you get the following
Histogram and PDFs for one gaussian
Again, the pdf from gmdistribution doesn't fit the histogram. It seems that the problem is with the scaling factor in the data generation (the 0.35). What am I doing wrong?
The Sigma parameter of the gmdistribution object corresponds to the covariance, however, the normpdf function needs the standard deviation. The problem is fixed by replacing normpdf(x,u,sigma) with normpdf(x,u,sqrt(sigma)) in the for loop.

Compute a histogram() without plotting in matlab

Is there a way to get the result object of a call to histogram() without the histogram plot?
I want to use the results in a script without figures being generated.
Thanks.
On octave you can use
values = hist(...);
without generating a plot. hist will also return the bin centers if you provide a second output argument. Note that Mathworks recommends using histogram and histcounts (see below) instead. You may also be interested in histc which takes the position of the bin edges as an input.
On current Matlab versions you can also use histcounts to get the bin counts and edges.
Please see also the documentation of hist and histcounts.

how to get the area of a region using matlab

I want to plot some equations and inequalities like x>=50, y>=0,4x-5y>=8,x=40,x=60,y=25, y=45 in matlab and want to get the area produced by intersecting these equations and inequalities. Is it possible using matlab? If yes can someone provide me some manual? If not, is there some other software that can do this?
Integrals would work for your purposes, provided you know the points at which the curves intersect (something Matlab is also able to compute). Take a look at the documentation on the integral function.
q = integral(fun,xmin,xmax) approximates the integral of function fun
from xmin to xmax using global adaptive quadrature and default error
tolerances.
EDIT: As an additional resource, take a look at the code provided by user Grzegorz Konz on the Mathworks blog.
EDIT #2: I'm not familiar with any Matlab functions that'll take a vector of functions and return the points of intersection (if any) between all the curves. Users have produced functions that return the set of intersection points between two curves. You could run this function for each pair of equations in your list and use a function like polyarea to compute the area of the enclosed region if the curves are all straight lines.