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:
Output adjusted 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:
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 :
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:
Related Topics
All K Nearest Neighbors in 2D, C++
Overloading Postfix and Prefix Operators
Cannot Evaluate Function -- May Be Inlined
Xlib How Does This (Removing Window Decoration) Work
Why Is Operator""S Hidden in a Namespace
Convert Byte Array into Bitset
Macro and Member Function Conflict
Best C++ Matrix Library for Sparse Unitary Matrices
How to Find the Minimum Value in a Map
Compiler Support for Upcoming C++0X
Why Does Gcc Not Seem to Have the Filesystem Standard Library
What Is a Possible Workaround for Object Slicing in C++
How Could I Sensibly Overload Placement Operator New
Programmatically Getting Per-Process Disk Io Statistics on Windows
Gcc 7, -Wimplicit-Fallthrough Warnings, and Portable Way to Clear Them