C/C++ development, opencv threshold operation

Table of contents

1. OpenCV-threshold operation

1.1 Threshold operation function threshold

1.2threshold operation type

1.3Otsu algorithm

2. Sample development

2.1 Makefile

2.2 main.cpp

2.3 Operation effect

3. OpenCV-adaptive threshold operation

        3.1 Adaptive threshold operation function-adaptiveThreshold

3.2 Sample development


1. OpenCV-threshold operation

1.1 Threshold operation function threshold

        In OpenCV, threshold operation is a basic image processing method used to convert grayscale images into binary images. This operation works by comparing each pixel value of the input image using a set threshold (thresh), and setting the pixel value to 0 or the maximum value (maxval) based on the comparison result. There are five different types of threshold operations, including binary thresholding, anti-binary thresholding, truncation thresholding, thresholding to 0, and anti-thresholding to 0.

        In the OpenCV-C++ source code, its threshold operation function is defined in \opencv2\imgproc.hpp:

@param src input array (multiple-channel, 8-bit or 32-bit floating point).
@param dst output array of the same size  and type and the same number of channels as src.
@param thresh threshold value.
@param maxval maximum value to use with the #THRESH_BINARY and #THRESH_BINARY_INV thresholding
types.
@param type thresholding type (see #ThresholdTypes).
@return the computed threshold value if Otsu's or Triangle methods used.

@sa  adaptiveThreshold, findContours, compare, min, max
 */
CV_EXPORTS_W double threshold( 
    InputArray src, 
    OutputArray dst,         
    double thresh, 
    double maxval, 
    int type );

        The function threshold applies a fixed level threshold setting to a multi-channel array. This function is typically used to obtain a bilayer (binary) image from a grayscale image or for noise removal, i.e. filtering out pixel values ​​that are too small or too large. This function supports several types of thresholding. They consist of type parameters. Additionally, the special values ​​#THRESH_OTSU or #THRESH-TRIANGLE can be combined with the above values. In these cases, the function uses the Otsu or trigonometric algorithm and uses it instead of the specified threshold. Note: Currently, the Otsu and Triangle methods only work with 8-bit single-channel images.

1.2threshold operation type

        If you know something about the convolution kernel, you can also think of the threshold operation as convolution with a 1*1 kernel, performing a nonlinear operation on each pixel.

        In OpenCV, there are five types of threshold operations (int type), namely:

  1. THRESH_BINARY = 0: Binarization, if it is greater than the threshold, it is 255, and if it is less than the threshold, it is 0.
  2. THRESH_BINARY_INV = 1: Anti-binarization, the value greater than the threshold is 0, and the value less than the threshold is 255.
  3. THRESH_TRUNC = 2: truncation method, the value greater than the threshold is taken as the threshold, and the value less than the threshold remains unchanged.
  4. THRESH_TOZERO = 3: If it is greater than the threshold, it will remain unchanged, and if it is less than the threshold, it will be 0.
  5. THRESH_TOZERO_INV = 4: If it is greater than the threshold, it will be 0, and if it is less than the threshold, it will not change.

        When using, you can choose the corresponding type according to actual needs.

1.3Otsu algorithm

        The function cv::threshold can automatically determine the optimal threshold. You only need to pass THRESH_OTSU to the parameter thresh. The Otsu algorithm is an algorithm for determining the optimal threshold for image binarization. Its principle is to use the maximum inter-class variance method to determine the threshold of the image, thereby segmenting the image into foreground and background parts.

        The basic idea of ​​the Otsu algorithm is: Assume that the height of the input image is and the width is, which represents the grayscale histogram of the image obtained by normalization, and represents the proportion of the number of pixels with grayscale values ​​equal to that in the image. First, calculate the zero-order cumulative moment (also called the cumulative histogram) and the first-order cumulative moment of the grayscale histogram; then, calculate the overall grayscale average of the image, which is actually the first-order cumulative moment; then, for each Each gray level is used as a threshold to calculate the variance of the average gray level of the foreground area, the average gray level of the background area and the average gray level of the entire image. The following measures are used to measure the variance; finally, find the value that maximizes the inter-class variance. The corresponding gray level is used as the optimal threshold.

        The Otsu algorithm is an adaptive threshold determination method with simple calculation and high efficiency, but it is not very effective in processing images with uneven illumination.

2. Sample development

2.1 Makefile

For information on opencv editing, library generation, and calling, please refer to the previous blog post of this column, which will not be expanded here. Compilation command: mingw32-make -j4 or make -4.

#/bin/sh
CX= g++ 

BIN 		:= ./
TARGET      := transform_img1.exe
FLAGS		:= -std=c++11 -static
SRCDIR 		:= ./
#INCLUDES
INCLUDEDIR 	:= -I"../../opencv_MinGW/include" 
#-I"$(SRCDIR)"
staticDir   := ../../opencv_MinGW/x64/mingw/staticlib/
#LIBDIR		:= $(staticDir)/libopencv_world460.a\
#			   $(staticDir)/libade.a \
#			   $(staticDir)/libIlmImf.a \
#			   $(staticDir)/libquirc.a \
#			   $(staticDir)/libzlib.a \
#			   $(wildcard $(staticDir)/liblib*.a) \
#			   -lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
#opencv_world放弃前,然后是opencv依赖的第三方库,后面的库是MinGW编译工具的库

LIBDIR 	    := -L $(staticDir) -lopencv_world460 -lade -lIlmImf -lquirc -lzlib \
				-llibjpeg-turbo -llibopenjp2 -llibpng -llibprotobuf -llibtiff -llibwebp \
				-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
source		:= $(wildcard $(SRCDIR)/*.cpp) 

$(TARGET) :
	$(CX) $(FLAGS) $(INCLUDEDIR) $(source)  -o $(BIN)/$(TARGET) $(LIBDIR)

clean:
	rm  $(BIN)/$(TARGET)

2.2 main.cpp

#include "opencv2/opencv.hpp" //Include file for every supported OpenCV function 
#include <iostream>
#include <vector>
using namespace std;
//阀值化
void sum_rgb1( const cv::Mat& src, cv::Mat& dst )
{
	// Split image onto the color planes
	//
	vector< cv::Mat> planes;
	cv::split(src,planes);
	cv::Mat b = planes[0],g = planes[1],r = planes[2],s;
	// Add equally weighted rgb values
	//
	cv::addWeighted( r,1./3., g,1./3., 0.0,s );
	cv::addWeighted( s,1., b,1./3.,0.0,s );
	// Truncate values above 100
	//
	cv::threshold( s,dst,100,100,cv::THRESH_TRUNC );
}
//组合与阀值图像平面
void sum_rgb2( const cv::Mat& src,cv::Mat& dst )
{
	// Split image onto the color planes
	//
	vector<cv::Mat> planes;
	cv::split(src,planes);
	cv::Mat b = planes[0],g = planes[1],r= planes[2];
	// Accumulate separate planes, combine and threshold
	//
	cv::Mat s = cv::Mat::zeros(b.size(),CV_32F);
	cv::accumulate(b,s);
	cv::accumulate(g,s); 
	cv::accumulate(r,s);
	// Truncate values above 100 and rescale into dst.
	cv::threshold( s,s,100,100,cv::THRESH_TRUNC );
	s.convertTo(dst,b.type());
}

void help()
{
	cout <<"Call: ./1.PNG"<< endl;
	cout << "Shows use of alpha blending (addweighted) and threshold" << endl;
}

int main(int argc,char** argv){
	help();
	if(argc< 2){ cout <<"specify input image" << endl; return -1;}
	// Load the image from the given file name
	//
	cv::Mat src = cv::imread( argv[1] ),dst;
	if( src.empty() ){
		cout << "can not load " << argv[1] << endl; 
		return -1;
	}
	// sum_rgb1( src,dst);
	sum_rgb2( src,dst);
	// Create a named window with the name of the fle and
	// show the image in the window1
	cv::imshow( argv[1],dst );
	// Idle until the user hits any key
	//
	cv::waitKey(0);
	return 0;
}

2.3 Operation effect

3. OpenCV-adaptive threshold operation

        3.1 Adaptive threshold operation function-adaptiveThreshold

        The adaptive threshold operation adaptiveThreshold is different from the previous thresholding method in that the threshold automatically changes during the entire process. Also defined in \opencv2\imgproc.hpp. In OpenCV, adaptive threshold operation is a more advanced threshold processing method used to process images with non-uniform brightness. The basic idea of ​​adaptive threshold operation is: for each pixel, the pixel values ​​of its neighbors are used to calculate its threshold. The pixel value in this neighborhood usually includes the 8 or 16 pixels surrounding the pixel. The advantage of this method is that it can better adapt to the non-uniform brightness of the image.

@param src Source 8-bit single-channel image.
@param dst Destination image of the same size and the same type as src.
@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied
@param adaptiveMethod Adaptive thresholding algorithm to use, see #AdaptiveThresholdTypes.
The #BORDER_REPLICATE | #BORDER_ISOLATED is used to process boundaries.
@param thresholdType Thresholding type that must be either #THRESH_BINARY or #THRESH_BINARY_INV,
see #ThresholdTypes.
@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the
pixel: 3, 5, 7, and so on.
@param C Constant subtracted from the mean or weighted mean (see the details below). Normally, it
is positive but may be zero or negative as well.

@sa  threshold, blur, GaussianBlur
 */
CV_EXPORTS_W void adaptiveThreshold( 
    InputArray src, 
    OutputArray dst,
    double maxValue, 
    int adaptiveMethod,
    int thresholdType, 
    int blockSize, 
    double C );

参数:
    src:输入图像,应该是灰度图像。
    dst:输出图像
    maxValue:输出图像的最大值。
    adaptiveMethod:自适应阈值算法的选择,可以是ADAPTIVE_THRESHOLD_MEAN_C或ADAPTIVE_THRESHOLD_GAUSSIAN_C。
    thresholdType:阈值类型,通常是THRESH_BINARY或THRESH_BINARY_INV。
    blockSize:用于计算阈值的邻域大小。
    C:加到阈值上的常数,以调整阈值。

        cv::adaptiveThreshold() allows two different adaptive threshold methods according to the setting of adaptiveMethod. Both methods calculate the adaptive threshold T(x,y) pixel by pixel by calculating the weighted average of the b*b area around each pixel position and then subtracting the constant C, where b is given by blocksize. . The difference is that if the average method selected is cv::ADAPTIVE THRESH MEAN C, then the weights obtained when averaging are equal. If the average method selected is cv::ADAPTIVE THRESH GAUSSIAN C (x, y), the weights of the surrounding pixels are equal. The weight is obtained through the Gaussian equation based on its distance to the center point.
        For the thresholdType threshold type, the type of the adaptiveThreshold function is the same as the type of the threshold function. Compared with the general thresholding operation, adaptive thresholding is very effective when there is a large difference between light and dark in the image. This function only handles single-channel 8-bit or floating point images, and requires that the source and destination images are different.

3.2 Sample development

        Makefile file is almost the same as the previous Makefile file, only the output program name is adjusted:

#TARGET      := transform_img1.exe
TARGET      := transform_img2.exe

       Compile command: mingw32-make -j4 or make -4

        main.cpp implementation

#include "opencv2/opencv.hpp" //Include file for every supported OpenCV function 

#include<iostream>
using namespace std;
int main( int argc,char** argv )
{
	if(argc != 7){ 
		cout <<"Usage:"<<argv[0] <<"fixed_threshold invert(0=offl1=on)"
		"adaptive_type(0=mean]1=gaussian) block_size offset image\n"
		"Example:"<<argv[0] <<"100 1 0 15 10 1.PNG"; 
		return -1;
	}
	// Command line
	double fixed_threshold = (double)atof(argv[1]);

	int threshold_type = atoi(argv[2]) ? cv::THRESH_BINARY : cv::THRESH_BINARY_INV;
	int adaptive_method = atoi(argv[3]) ? cv::ADAPTIVE_THRESH_MEAN_C : cv::ADAPTIVE_THRESH_GAUSSIAN_C;
	int block_size = atoi(argv[4]);
	double offset =(double)atof(argv[5]);
	cv::Mat Igray = cv::imread(argv[6], cv::IMREAD_GRAYSCALE);
	// Read in gray image
	//
	if( Igray.empty() ){ 
		cout << "Can not load " << argv[6] << endl; 
		return -1; 
	}
	// Declare the output images.
	//
	cv::Mat It,Iat;
	// Thresholds
	
	cv::threshold(
	Igray,
	It,
	fixed_threshold,
	255,
	threshold_type);
	cv::adaptiveThreshold(
	Igray,
	Iat ,
	255,
	adaptive_method,
	threshold_type,
	block_size,
	offset	);
	// Show the results.
	//
	cv::imshow("Raw",Igray);
	cv::imshow("Threshold",It);
	cv::imshow("Adaptive Threshold",Iat);

	cv::waitKey(0);
	return 0;
}

        The running effect is as follows:

Guess you like

Origin blog.csdn.net/py8105/article/details/133200475