Notas de estudio de OpenCV+MFC (2): OpenCV binariza las imágenes y las muestra de forma adaptativa en Picture Control

En el anterior hemos completado la lectura de imágenes en Picture Control a través de OpenCV y mostrándolas de forma adaptativa . Luego, naturalmente necesitamos procesar las imágenes leídas.Después del procesamiento, naturalmente pensamos en observar el efecto. Entonces, la nota de hoy es procesar la imagen a través de la escala de grises de OpenCV y mostrar el resultado.

Descripción del requisito

como muestra la imagen,

S1, el botón de arriba abre el administrador de recursos, carga una imagen en la pantalla adaptable Picture Control a la izquierda;

S2, el botón a continuación procesa la imagen cargada a través de la escala de grises de OpenCV y luego la muestra de forma adaptativa en el control de imagen a la derecha;

S3, ajuste el umbral a través de la barra de desplazamiento a continuación, observe y reconozca perceptivamente los diferentes efectos de la escala de grises bajo diferentes umbrales.

 

procesamiento en escala de grises

Según tengo entendido en Novice Village, si el último paso del preprocesamiento de imágenes digitales es la binarización de la imagen, entonces el primer paso es la escala de grises de la imagen.

El propósito del procesamiento de imágenes en escala de grises es simplemente digitalizar la imagen para facilitar el desarrollo y análisis de tecnología.

Cada píxel de una imagen en escala de grises solo necesita un byte para almacenar el valor de escala de grises (también conocido como valor de intensidad, valor de brillo) y el rango de escala de grises es de 0 a 255. Las imágenes en escala de grises suelen medir cada píxel en un solo espectro de ondas electromagnéticas (como luz visible) obtenido por el brillo. Las imágenes en escala de grises para visualización generalmente se almacenan con una escala no lineal de 8 bits por píxel de muestra, lo que permite 256 niveles de escala de grises. Este tipo de precisión es suficiente para evitar la distorsión de bandas visibles y es muy fácil de programar.

binarización

La binarización de la imagen consiste en establecer el valor de gris de los píxeles de la imagen en 0 o 255, lo que hará que toda la imagen parezca un efecto obvio en blanco y negro. En el procesamiento de imágenes digitales, la imagen binaria ocupa una posición muy importante. La binarización de la imagen reduce en gran medida la cantidad de datos en la imagen, resaltando así el contorno del objetivo.

Desde el punto de vista de la programación, se puede entender como convertir la información compleja de píxeles en la imagen en datos binarios que son 0 o 1, o 1 o 0, lo cual es conveniente para nuestros cálculos.

//第二个按钮的响应事件代码
void CmyMFCDlg::OnBnClickedBinary()
{
	// TODO: 在此添加控件通知处理程序代码
	Mat dst_mat;//左边载入的图片对象

	//S1,灰度处理
	cv::cvtColor(src_mat, dst_mat, cv::COLOR_BGR2GRAY);

	//S2,开始二值化
	//第二个和第三个参数是阀值,决定了二值化显示的效果.如果设定不正确可能图像显不出来	
	cv::threshold(dst_mat, dst_mat, 127, 255, cv::THRESH_BINARY);

	//S3,展示图片处理后的效果
	DrawMat(dst_mat, IDC_STATIC_RESULT);
}

Hablando brevemente sobre el método de binarización cv::threshold, hay un total de 5 parámetros, preste atención a los parámetros 3 y 5.

El tercero es el umbral y el quinto es el tipo de algoritmo de umbral.

¿Cómo entender el umbral aquí? Por ejemplo, si nuestra cámara toma una foto con un ángulo y parámetros fijos, la imagen resultante puede ser diferente debido a los cambios en la fuente de luz (como los cambios en la luz del sol, como la luz y la oscuridad). No podemos binarizar la imagen de manera simple y aproximada, lo que puede conducir a la pérdida de información de píxeles que debería ser 1, pero recopilar y ampliar la información de píxeles que debería ser 0.

La mayoría de las veces, en el entorno de la línea de montaje industrial, dado que la fuente de luz y el ángulo son relativamente fijos, el valor de umbral se puede establecer a través del valor de experiencia después de una depuración repetida para establecer un valor de umbral óptimo y un tipo de algoritmo de umbral. Pero cuando el entorno de la fuente de luz cambia mucho, este umbral requiere más energía para calcularse.

Echemos un vistazo a la misma imagen, el efecto de la imagen en diferentes umbrales:

 

 

Al ver que el cambio del control deslizante conduce al cambio del umbral, también conduce al cambio del efecto después de la binarización, qué valores son útiles, qué valores calcularán qué resultados, cuáles tendrán diferentes umbrales para traer resultados diferentes.

¿Sabes cuán poderoso es este umbral? 

En cuanto al tipo de algoritmo de umbral del quinto parámetro de cv::threshold, también complementa el valor de umbral, estos son relativamente completos y fáciles de consultar en Internet, así que no diré más.

Finalmente, publique el tercer requisito mencionado al principio del artículo: la imagen procesada por OpenCV debe mostrarse en Picture Control.

//参数1:要显示的图对象  
//参数2:Picture Control控件的ID
void CmyMFCDlg::DrawMat(cv::Mat& img, UINT nID)
{
	CRect rect;
	cv::Mat imgTmp;

	GetDlgItem(nID)->GetClientRect(&rect);  // 获取控件大小
	cv::resize(img, imgTmp, cv::Size(rect.Width(), rect.Height()));// 缩放Mat并备份
	// 再重新灰度处理下,备用 
	switch (imgTmp.channels())
	{
	case 1:
		cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道
		break;
	case 3:
		cv::cvtColor(imgTmp, imgTmp, CV_BGR2BGRA);  // BGR三通道
		break;
	default:
		break;
	}
	int pixelBytes = imgTmp.channels() * (imgTmp.depth() + 1); // 计算一个像素多少个字节
	// 制作bitmapinfo(数据头)
	BITMAPINFO bitInfo;
	bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
	bitInfo.bmiHeader.biWidth = imgTmp.cols;
	bitInfo.bmiHeader.biHeight = -imgTmp.rows;
	bitInfo.bmiHeader.biPlanes = 1;
	bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bitInfo.bmiHeader.biCompression = BI_RGB;
	bitInfo.bmiHeader.biClrImportant = 0;
	bitInfo.bmiHeader.biClrUsed = 0;
	bitInfo.bmiHeader.biSizeImage = 0;
	bitInfo.bmiHeader.biXPelsPerMeter = 0;
	bitInfo.bmiHeader.biYPelsPerMeter = 0;
	// Mat.data + bitmap数据头 -> MFC
	CDC* pDC = GetDlgItem(nID)->GetDC();
	::StretchDIBits(
		pDC->GetSafeHdc(),
		0, 0, rect.Width(), rect.Height(),
		0, 0, rect.Width(), rect.Height(),
		imgTmp.data,
		&bitInfo,
		DIB_RGB_COLORS,
		SRCCOPY
	);
	ReleaseDC(pDC);
}

Como principiante doble en MFC y procesamiento de imágenes, es difícil de aprender, pero siempre habrá ganancias con el tiempo, ¡así que adelante!

Supongo que te gusta

Origin blog.csdn.net/laolitou_1024/article/details/124509445
Recomendado
Clasificación