MFC and HALCON mixed programming four auto_ Thorhold principle

introduction

auto_threshold - segment the image using the threshold determined from the histogram.
auto_threshold uses multiple thresholds to segment a single channel image.

Firstly, the absolute histogram of gray value is determined.

Then, the relevant minimum values are extracted from the histogram, which are continuously used as the parameters of threshold operation. The thresholds for byte images are 0, 255, and all minimum values extracted from the histogram (after the histogram is smoothed using a Gaussian filter with a standard deviation of Sigma).

For each gray value interval, a region is generated. Therefore, the number of regions is the minimum number + 1. For uint2 images, the above procedure is used similarly. However, the highest threshold here is 65535.

In addition, for uint2 images, the value of Sigma (actually) refers to a histogram with 256 values, although a higher resolution histogram is used internally. This is done to facilitate switching between image types without changing the parameter Sigma. For floating-point images, the threshold is the minimum and maximum gray values in the image and all the minimum values extracted from the histogram. Here, the scaling of the parameter Sigma refers to the original gray value of the image.

The larger the value of Sigma, the less regions are extracted. This operator is useful if the region to be extracted shows similar gray values (homogeneous regions).

auto_threshold(Image : Regions : Sigma : )
/*
Image (input_object)
Enter an image.
Regions (output_object)
An area with a gray value within an automatically determined interval.
Sigma (input_control) 
Sigma Gaussian smoothing for histogram.
Default: 2.0
 Recommended values: 0.0, 0.5, 1.0, 2.0, 3.0, 4.0, 5.0
 Typical value range: 0.0 ≤ Sigma ≤ 100.0 (lin)
Minimum increment: 0.01
 Recommended increment: 0.3
 Limit: sigma > = 0.0
*/

1, Results

1.1 Halcon presentation results


1.2 MFC demonstration results


2, Halcon code

dev_close_window ()
read_image (Aegypt1, 'egypt1')
get_image_size (Aegypt1, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowID)
set_display_font (WindowID, 14, 'mono', 'true', 'false')
dev_set_colored (6)
dev_clear_window ()
Sigma := 4
auto_threshold (Aegypt1, Regions, Sigma)
gray_histo (Aegypt1, Aegypt1, AbsoluteHisto, RelativeHisto)
disp_continue_message (WindowID, 'black', 'true')
stop ()
dev_clear_window ()
create_funct_1d_array (AbsoluteHisto, Function)
smooth_funct_1d_gauss (Function, Sigma, SmoothedFunction)
dev_set_color ('red')
funct_1d_to_pairs (SmoothedFunction, XValues, YValues)
gen_region_histo (Histo1, YValues, 255, 255, 1)
dev_display (Aegypt1)
dev_set_color ('white')
gen_region_histo (Histo2, RelativeHisto, 255, 255, 1)

3, MFC source code

1. Main code of header file

public:
	MyAssist myassist;
	HTuple picture1_WindowID,picture2_WindowID;
	CWnd *pWnd;
	// Local iconic variables
	HObject  ho_Aegypt1, ho_Regions, ho_Histo1, ho_Histo2;
	// Local control variables
	HTuple  hv_Width, hv_Height, hv_WindowID, hv_Sigma;
	HTuple  hv_AbsoluteHisto, hv_RelativeHisto, hv_Function;
	HTuple  hv_SmoothedFunction, hv_XValues, hv_YValues;
public:
	afx_msg void OnBnClickedButtonReadImg();
	afx_msg void OnBnClickedButtonProcessImg();

2. Main source code

void CHalconMFCDlg::OnBnClickedButtonReadImg()
{
	// TODO: add control notification handler code here
	CRect rect;
	pWnd = GetDlgItem(IDC_STATIC_ORIGINAL_IMG);
	picture1_WindowID = (Hlong)pWnd->m_hWnd;
	pWnd->GetWindowRect(&rect);

	ReadImage(&ho_Aegypt1, "egypt1");
	GetImageSize(ho_Aegypt1, &hv_Width, &hv_Height);
	SetWindowAttr("background_color", "black");
	OpenWindow(0, 0, rect.Width(), rect.Height(), picture1_WindowID, "visible", "", &hv_WindowID);
	HDevWindowStack::Push(hv_WindowID);
	if (HDevWindowStack::IsOpen())
		SetDraw(HDevWindowStack::GetActive(), "margin");
	if (HDevWindowStack::IsOpen())
		SetLineWidth(HDevWindowStack::GetActive(), 3);
	if (HDevWindowStack::IsOpen())
		DispObj(ho_Aegypt1, HDevWindowStack::GetActive());
	
}


void CHalconMFCDlg::OnBnClickedButtonProcessImg()
{
	// TODO: add control notification handler code here
	CRect Rect;
	pWnd = GetDlgItem(IDC_STATIC_PROCESS_IMAGE);
	picture2_WindowID = (Hlong)pWnd->m_hWnd;
	pWnd->GetWindowRect(&Rect);
	OpenWindow(0, 0, Rect.Width(), Rect.Height(), picture2_WindowID, "visible", "", &hv_WindowID);
	HDevWindowStack::Push(hv_WindowID);
	myassist.set_display_font(hv_WindowID, 14, "mono", "true", "false");
	if (HDevWindowStack::IsOpen())
		SetColored(HDevWindowStack::GetActive(), 6);
	if (HDevWindowStack::IsOpen())
		ClearWindow(HDevWindowStack::GetActive());
	hv_Sigma = 4;
	AutoThreshold(ho_Aegypt1, &ho_Regions, hv_Sigma);
	GrayHisto(ho_Aegypt1, ho_Aegypt1, &hv_AbsoluteHisto, &hv_RelativeHisto);
	//myassist.disp_continue_message(hv_WindowID, "black", "true");
	// stop(); only in hdevelop
	if (HDevWindowStack::IsOpen())
		ClearWindow(HDevWindowStack::GetActive());
	CreateFunct1dArray(hv_AbsoluteHisto, &hv_Function);
	SmoothFunct1dGauss(hv_Function, hv_Sigma, &hv_SmoothedFunction);
	if (HDevWindowStack::IsOpen())
		SetColor(HDevWindowStack::GetActive(), "red");
	Funct1dToPairs(hv_SmoothedFunction, &hv_XValues, &hv_YValues);
	GenRegionHisto(&ho_Histo1, hv_YValues, 255, 255, 1);
	DispObj(ho_Histo1, HDevWindowStack::GetActive());
	/*if (HDevWindowStack::IsOpen())
		DispObj(ho_Aegypt1, HDevWindowStack::GetActive());*/
	if (HDevWindowStack::IsOpen())
		SetColor(HDevWindowStack::GetActive(), "white");
	GenRegionHisto(&ho_Histo2, hv_RelativeHisto, 255, 255, 1);
	if (HDevWindowStack::IsOpen())
	DispObj(ho_Histo2, HDevWindowStack::GetActive());
	
}

Analysis and summary

When the gray value of the image is different, the region where the target is located can be extracted by threshold segmentation. Common operators are:
1.auto_threshold — The image is segmented using the threshold determined from the histogram.
2.bin_threshold — The image is segmented using an automatically determined threshold.

bin_threshold uses an automatically determined threshold to segment a single channel gray value image. Firstly, the relative histogram of gray value is determined. Then, the relevant minimum value is extracted from the histogram and used as the parameter of threshold operation. In order to reduce the number of minimum values, the histogram is smoothed with Gaussian, such as auto_threshold. The mask size is enlarged until there is only a minimum value in the smooth histogram. The selected area contains pixels with grayscale values from 0 to the minimum, or from the minimum to the respective minimum for real images. For example, this operator can be used to split dark characters on light paper.

3.char_threshold — Perform threshold segmentation to extract characters.

char_ The main application of threshold is to segment the single channel Image of dark characters on bright paper. The working principle of this operator is as follows: firstly, the histogram of gray value in Image is calculated for the points in HistoRegion {} region. In order to eliminate noise, the histogram is smoothed using a given Sigma (Gaussian smoothing). In the histogram, the background (white paper) corresponds to a large peak at the high gray value, while the character forms a small peak at the low gray value. And the operator binary that locates the minimum value between two peaks_ Compared with threshold (with 'Method' = 'smooth_histo'), the segmentation threshold here is the following conditions determined with respect to the maximum value (i.e. background) of the histogram:
histogram[threshold] * 100.0 < histogram[maximum] * (100.0 - Percent)
For example, if you select percentage = 95, the operator will locate a grayscale value with a frequency of up to 5% of the maximum frequency. Because char_threshold assumes that the character is darker than the background, so search the "left" of the maximum threshold.
And binary_ Compared with threshold, this operator should be used if there is no clear minimum value between the histogram peaks corresponding to the character and background respectively, or there is no peak corresponding to the character at all. This can happen, for example, if the image contains only a few characters or in the case of non-uniform illumination.

4.check_difference — Compare two images pixel by pixel.

check_difference selects those pixels from the input Image (g {o} = g {Image}), and the difference between the gray value and the corresponding pixel in the Pattern is inside (outside) the interval [DiffLowerBound,DiffUpperBound]. The pixels of the Pattern are converted by (AddRow,AddCol) relative to the Image. Ling g_{p} Is determined by (AddRow,AddCol) relative to g_ {o} The grayscale value of the translated Pattern.

If the selected Mode is' diff '_ 'inside', select a pixel g_{o} , if

If the mode is set to 'diff'_ 'outside', select a pixel g_{o} , if
g_ o - g_ P - grayoffset < difflowerbound or
g_o - g_p - GrayOffset > DiffUpperBound.
The test is performed for all points in the Image domain (region) and intersects the converted Pattern domain. All points that meet the above conditions are clustered in the output area. The size of the two images may be different. In general, Pattern is smaller than Image.

5.dual_threshold — Threshold operator for the signature image.

dual_threshold divides the input image into areas with gray value > = threshold ("positive" areas) and areas with gray value < = - threshold ("negative" areas). Only "positive" or "negative" areas with a size greater than MinSize are considered. And the area where the absolute value of the maximum gray value is less than MinGray is suppressed.
The segmentation performed is incomplete, that is, the "positive" and "negative" areas do not necessarily cover the whole image together: areas with gray values between - Threshold and Threshold, - MinGray and MinGray are not considered
dual_threshold usually calls Laplasse operator (Laplace, laplace_of_gauss, derivate_gauss or diff_of_gauss) after image or two image differences (sub_image).
The zero intersection of Laplacian image corresponds to the edge of the image and is the separation area of "positive" and "negative" areas in Laplacian image. They can call dual by using Threshold = 1_ Threshold, and then use the complement to create the complement region. The parameter MinGray determines the noise invariance, and MinSize determines the resolution of edge detection.
With byte images, only the positive part of the operator is applied. Therefore, dual_ The behavior of threshold is similar to that with continuous join and select_gray's standard threshold operator (threshold).

6.dyn_threshold — The image is segmented using local threshold.

1394 / 5000
Translation results
dyn_threshold selects those areas where the pixels meet the threshold conditions from the input image. Set g_{o} = g_{OrigImage}, and g_{t} = g_{ThresholdImage}. Then the condition of LightDark = 'light' is:

For LightDark = 'dark', the condition is:

For LightDark = 'equal', it is:

Finally, for LightDark = 'not_equal ', which is:

Typically, the threshold image is a smooth version of the original image (for example, by applying mean_image, binomial_filter, gauss_filter, etc.). Then dyn_ The effect of threshold is similar to applying a threshold to a high pass filtered version of the original image (see highpass_image).

Using dyn_threshold, the contour of the object can be extracted, where the size (diameter) of the object is determined by the mask size of the low-pass filter and the amplitude of the edge of the object:

The larger the mask size selected, the larger the area found. As a rule of thumb, the mask size should be about twice the diameter of the object to be extracted. It is important not to set the parameter Offset to zero, because too many small areas (noise) will be found in this case. A value between 5 and 40 is a useful choice. The larger the Offset selected, the smaller the extracted area.

All points of the input image satisfying the above conditions are stored in one area. If necessary, you can get the connected components by calling connection.

Tags: ElasticSearch MFC microsoft

Posted on Tue, 02 Nov 2021 03:16:51 -0400 by evlive