1, Image enhancement
1. What is image enhancement
Image enhancement is the technology of processing images to obtain images with better visual effect or more "useful" for specific applications.
2. Why image enhancement
In the process of image transmission or processing, noise will be introduced or the image will become blurred, which reduces the image quality and even drowns the features, which brings difficulties to the analysis.
3. Purpose of image enhancement
① Improve the visual effect of the image and improve the definition of the image;
② Convert the image into a form more suitable for human or machine analysis and processing.
③ Note: in the process of image enhancement, there is no addition of new information, but by suppressing one part of the information to highlight another part of the information.
4. Classification and process of image enhancement methods
(1) Airspace method
Directly operate the pixel gray value of the image.
Including image gray transformation, histogram correction, smoothing and sharpening, color enhancement and so on.
(2) Frequency domain method
In the transformation domain of the image, the transformation value of the image is operated, and then the required enhancement result is obtained by inverse transformation.
Common methods include low-pass filtering, high-frequency lifting filtering and homomorphic filtering.
2, Basic concepts
1. Gray scale transformation of image
If the original image is f(m,n) and the processed image is g(m,n), the contrast enhancement can be expressed as:
Where T[i] represents the gray transformation relationship (function) between the enhanced image and the original image.
3, Gray linear transformation
1. Linear transformation
Let the gray value f(m,n) ∈ [a,b] of the original image, the value g(m,n) ∈ [c,d] after linear transformation, and the transformation relationship is:
amongIt is called the slope of the transformation function (straight line).
2. Piecewise linear transformation
(1) Expand your interests at the expense of others
The [a,b] interval of interest is extended by a linear transformation with a slope greater than 1, while other intervals are represented by a or B. The transformation function is
(2) Expand your interests and compress others
While expanding the [a,b] interval of interest, in order to preserve the gray level of other intervals, other interval compression methods can also be used, that is, expansion and compression. The transformation function is:
/*Contrast stretch piecewise linear transform*/ void Contrast_stretch(Mat& src,Mat& dst,double a,double b,double c,double d) { src.copyTo(dst); dst.convertTo(dst, CV_64F); double min = 0, max = 0; minMaxLoc(dst, &min, &max, 0, 0); //Find the global maximum and global minimum in the dst matrix (only for single channel) int nr = dst.rows; int nc = dst.cols * dst.channels(); if (dst.isContinuous()) //If the storage is continuous (storage between rows), the image can be regarded as a one-dimensional array { int nr = 1; int nc = dst.cols * dst.rows * dst.channels(); } for (int i = 0; i < nr; i++) { double* ptr_dst = dst.ptr<double>(i); //Pointer to the first element on line i for (int j = 0; j < nc; j++) { if (min <= ptr_dst[j] < a) { ptr_dst[j] = (c / a) * ptr_dst[j]; } else if (a <= ptr_dst[j] < b) { ptr_dst[j] = ((d - c) / (b - a)) * ptr_dst[j]; } else if (b <= ptr_dst[j] < max) { ptr_dst[j] = ((max - d) / (max - b)) * ptr_dst[j]; } } } dst.convertTo(dst, CV_8U); //Returns an unsigned octet image }
3. Nonlinear transformation
(1) Logarithmic transformation
among λ Is an adjustment constant, which is used to adjust the transformed gray value to meet the actual requirements.
The function of logarithmic transformation is to expand the low gray range of the image and compress the high gray range at the same time, so that the gray distribution of the image is uniform and matched with human visual characteristics. The inverse of the inverse transformation.
Logarithmic function has an important feature: it compresses the dynamic range of images with large changes in pixel values. Typically, spectral values range from 0 to 106 or even higher. Although the computer can process this range of numbers without problem, the image display system usually can not faithfully reproduce such a large range of gray values. Therefore, the final result is that many important gray details are lost in the display of typical Fourier spectrum.
/*Logarithmic transformation*/ void Log_trans(Mat& src, Mat& dst, double c) { int nr = src.rows; int nc = src.cols * src.channels(); src.copyTo(dst); dst.convertTo(dst, CV_64F); if (src.isContinuous() && dst.isContinuous()) { nr = 1; nc = src.rows * src.cols * src.channels(); } for (int i = 0; i < nr; i++) { const uchar* srcdata = src.ptr<uchar>(i); //Get the address at the beginning of line i double* dstdata = dst.ptr<double>(i); for (int j = 0; j < nc; j++) { dstdata[j] = c * log(double(1.0 + srcdata[j])); } } normalize(dst, dst, 0, 255, NORM_MINMAX); //Normalized data, dst.convertTo(dst, CV_8U); }
(2) Exponential transformation
Contrary to the effect of logarithmic transformation, exponential transformation expands the high gray range and compresses the low gray range.
among λ and γ Is a constant. To avoid a base of 0, increase the offset ε. γ The choice of values has a great influence on the characteristics of the transformation function γ< 1, the gray scale of the original image will be mapped to the high brightness part γ> When 1, it maps to the low brightness part, and when γ= 1 is equivalent to proportional transformation.
(3) Power law (gamma) transformation
Where c and γ Is a normal number;
γ< 1. Increase the gray level and brighten the image above the proportional function;
γ> 1 reduce the gray level and darken the image below the proportional function.
Example:
/*Exponential transformation: c-coefficient; r-index*/ void change_index(Mat& src, Mat& dst, double c, double r) { int nr = src.rows; int nc = src.cols; src.copyTo(dst); dst.convertTo(dst, CV_64F); if (src.isContinuous() && dst.isContinuous()) { nr = 1; nc = src.rows * src.cols * src.channels(); } for (int i = 0; i < nr; i++) { const uchar* srcdata = src.ptr<uchar>(i); //Get the address at the beginning of line i double* dstdata = dst.ptr<double>(i); for (int j = 0; j < nc; j++) { dstdata[j] = c * pow(srcdata[j], r); } } normalize(dst, dst, 0, 255, NORM_MINMAX); //Normalized data dst.convertTo(dst, CV_8U); }
Reference article: https://blog.csdn.net/weixin_40647819/article/details/88014295