Is There Any Function Equivalent to Matlab's Imadjust in Opencv with C++

Is there any function equivalent to Matlab's imadjust in OpenCV with C++?

There's no builtin solution in OpenCV to perform histogram stretching, but you can do it easily in a loop.

imadjust allows to select a tolerance for upper and lower bounds, or the bounds directly, so you need a little more logic than a simple for loop.

You can use the example below as a reference while implementing your own:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>

using namespace std;
using namespace cv;

void imadjust(const Mat1b& src, Mat1b& dst, int tol = 1, Vec2i in = Vec2i(0, 255), Vec2i out = Vec2i(0, 255))
{
// src : input CV_8UC1 image
// dst : output CV_8UC1 imge
// tol : tolerance, from 0 to 100.
// in : src image bounds
// out : dst image buonds

dst = src.clone();

tol = max(0, min(100, tol));

if (tol > 0)
{
// Compute in and out limits

// Histogram
vector<int> hist(256, 0);
for (int r = 0; r < src.rows; ++r) {
for (int c = 0; c < src.cols; ++c) {
hist[src(r,c)]++;
}
}

// Cumulative histogram
vector<int> cum = hist;
for (int i = 1; i < hist.size(); ++i) {
cum[i] = cum[i - 1] + hist[i];
}

// Compute bounds
int total = src.rows * src.cols;
int low_bound = total * tol / 100;
int upp_bound = total * (100-tol) / 100;
in[0] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), low_bound));
in[1] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), upp_bound));

}

// Stretching
float scale = float(out[1] - out[0]) / float(in[1] - in[0]);
for (int r = 0; r < dst.rows; ++r)
{
for (int c = 0; c < dst.cols; ++c)
{
int vs = max(src(r, c) - in[0], 0);
int vd = min(int(vs * scale + 0.5f) + out[0], out[1]);
dst(r, c) = saturate_cast<uchar>(vd);
}
}
}

int main()
{
Mat3b img = imread("path_to_image");

Mat1b gray;
cvtColor(img, gray, COLOR_RGB2GRAY);

Mat1b adjusted;
imadjust(gray, adjusted);

// int low_in, high_in, low_out, high_out
// imadjust(gray, adjusted, 0, Vec2i(low_in, high_in), Vec2i(low_out, high_out));

return 0;
}

Input image:

Sample Image

Output adjusted image:

Sample Image

Fast imadjust in OpenCV and python

Those answers are not very good. imadjust simply does a linear stretch. You need to find the lower and upper bound (by default it uses the 1% and 99% of the data). Once you have lower and upper, you can just

out = (img - lower) * (255 / (upper - lower)
np.clip(out, 0, 255, out) # in-place clipping

You probably need img to be of a floating-point type for that to work correctly.

See this question for linear mapping in Numpy.

equivalent function of sub2ind in opencv

A quick example to illustrate. Consider:

>> v = (1:4*3)
v =
1 2 3 4 5 6 7 8 9 10 11 12
>> M = reshape(v,[4 3])
M =
1 5 9
2 6 10
3 7 11
4 8 12

Now all the following are equivalent:

sz = size(M);

i = 3; j = 2;
M(i,j)
v( sub2ind(sz,i,j) )
v( sz(1)*(j-1)+i )

Just keep in mind that MATLAB uses a column-major order, while C is row-major order

How can I adjust contrast in OpenCV in C?

I think you can adjust contrast here in two ways:

1) Histogram Equalization :

But when i tried this with your image, result was not as you expected. Check it below:

Sample Image

2) Thresholding :

Here, i compared each pixel value of input with an arbitrary value ( which i took 127). Below is the logic which has inbuilt function in opencv. But remember, output is Binary image, not grayscale as you did.

If (input pixel value >= 127):
ouput pixel value = 255
else:
output pixel value = 0

And below is the result i got :

Sample Image

For this, you can use Threshold function or compare function

3) If you are compulsory to get grayscale image as output, do as follows:

(code is in OpenCV-Python, but for every-function, corresponding C functions are available in opencv.itseez.com)

for each pixel in image:
if pixel value >= 127: add 'x' to pixel value.
else : subtract 'x' from pixel value.

( 'x' is an arbitrary value.) Thus difference between light and dark pixels increases.

img = cv2.imread('brain.jpg',0)

bigmask = cv2.compare(img,np.uint8([127]),cv2.CMP_GE)
smallmask = cv2.bitwise_not(bigmask)

x = np.uint8([90])
big = cv2.add(img,x,mask = bigmask)
small = cv2.subtract(img,x,mask = smallmask)
res = cv2.add(big,small)

And below is the result obtained:

Sample Image



Related Topics



Leave a reply



Submit