Cómo calcular la dilatación y la corrosión en el procesamiento de imágenes digitales
Escanea cada píxel de la imagen con un elemento estructural de 3×3.
Realizar una operación AND sobre los elementos estructurales y sus imágenes binarias superpuestas.
Si ambos son 1, la imagen resultante tiene píxeles de 1. De lo contrario es 0.
Resultado: La imagen binaria se reduce en un círculo.
Definición: E = B? S = {x,y|Sxy? B}
Algoritmo de inflación:
Escanea cada píxel de la imagen con un elemento estructural de 3×3.
Realizar una operación AND sobre los elementos estructurales y sus imágenes binarias superpuestas.
Si ambos son 0, la imagen resultante tiene 0 píxeles. De lo contrario es 1.
Resultado: La imagen binaria se amplía en un círculo.
Definición: E = B? S = { x, y | Sxy∩B≠ф}
Código fuente para la dilatación
Dilatación booleana (HWND hWnd, nivel booleano)
{ p>
DWORD OffBits, BufSize
LPBITMAPINFOHEADER lpImgData
LPSTR lpPtr
HLOCAL hTempImgData
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpTempPtr
HDC hDc
HFILE hf
Long x, y;
Número de caracteres sin firmar;
int I;
// Para facilitar el procesamiento, todavía se usa la imagen en escala de grises de 256 niveles, pero solo se usan los elementos 0 y 255 en la paleta.
if(NumColors!=256){
MessageBox(hWnd, "¡Debe ser un mapa de bits monocromático con una paleta de escala de grises!",
"Mensaje de error" , MB_OK | MB_icon excepción);
Devuelve FALSE
}
off bits = BF off bits-sizeof (encabezado del archivo de mapa de bits);
//BufSize es el tamaño del búfer.
BufSize = off bits+bi . BIH height * line bytes;
//Asigna memoria para el nuevo búfer
if((htempmgdata = local alloc ( LHND, BufSize))==NULL)
{
MessageBox(hWnd, "¡Error al asignar memoria!", "Mensaje de error",
MB _ OK | MB_signo de exclamación);
Devolver FALSO
}
lpImgData =(LPBITMAPINFOHEADER)bloqueo global(himg data);
lpTempImgData = (LPBITMAPINFOHEADER)bloqueo local(htempmgdata);
//Copiar información del encabezado y datos de mapa de bits
memcpy(lpTempImgData, lpImgData, BufSize);
if(Hori )
{
//Realizar la operación de expansión horizontal.
for(y = 0; y & ltbi . BIH height; y++){
//lpPtr apunta a los datos originales, lpTempPtr apunta a los nuevos datos.
lpPtr =(char *)lpImgData+(BufSize-line bytes-y * line bytes)+1
lpTempPtr =(char *)lpTempImgData+
( BufSize-bytes de línea-y * bytes de línea)+1;
for(x = 1; x & ltbi . bi ancho-1; x++){
//Nota, para Para evitar que se salga de los límites, el rango de x es de 1 a -2.
num=(unsigned Character)* lpPtr
//La imagen original tiene puntos negros, y la nueva imagen también debe tenerlos, por lo que se deben considerar esas imágenes originales.
//Puntos blancos, comprueba si pueden expandirse hasta convertirse en puntos negros.
if (num==255){
*lpTempPtr=(unsigned Character)255; //Conviértelo en blanco primero
for(I = 0 ;i<3;i++){
num=(unsigned Character)*(lpPtr+I-1);
//Siempre que uno de los vecinos izquierdo y derecho sea un punto negro se expandirá hasta convertirse en un punto negro.
if(num==0){
*lpTempPtr=(unsigned char)0;
Romper;
}< / p>
}
}
//La imagen original tiene puntos negros, pero la nueva imagen todavía tiene puntos negros.
else *lpTempPtr=(unsigned char)0;
//Señala el siguiente píxel
lpptr++;
lptempptr++;
}
}
}
De lo contrario{
//Realice la operación de grabado vertical.
for(y = 1; y & ltbi . BIH height-1; Y++){ //Tenga en cuenta que el rango de Y es la altura de 1 a -2 para evitar cruzar el límite.
lpPtr =(char *)lpImgData+(BufSize-línea bytes-y * línea bytes);
lpTempPtr =(char *)lpTempImgData+(BufSize-línea bytes-y * línea bytes); ) );
for(x = 0; x & ltbi.biWidthx++){
num=(carácter sin firmar)* lpPtr
if (num== 255){
*lpTempPtr=(carácter sin firmar)255;
for(I = 0;i<3;i++){
num =( carácter sin firmar) *(lpPtr+(I-1)* bytes de línea);
//Mientras uno de los vecinos superior e inferior sea un punto negro, se expandirá hasta convertirse en un punto negro.
if(num==0){
*lpTempPtr=(unsigned char)0;
Romper;
}< / p>
}
}
else *lpTempPtr=(unsigned char)0;
lpptr++;
lptempptr++ ;
}
}
}
if(hBitmap!=null)
eliminar objeto(mapa hbit) ;
hDc = GetDC(hWnd);
//Generar un nuevo mapa de bits
hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData,
(LONG)CBM_INIT,
(LPSTR)lpTempImgData+
tamaño de(BITMAPINFOHEADER)+
NumColors*tamaño de(RGBQUAD),
p>
(LPBITMAPINFO)lpTempImgData,
DIB_RGB_COLORS);
//Diferentes nombres de archivos de resultados.
if(Hori)
hf=_lcreat("c:\\hdilation.bmp ", 0
Otros
); hf=_lcreat("c:\\vdilation.bmp ", 0);
_lwrite(hf, (LPSTR)&bf, sizeof(encabezado del archivo de mapa de bits));
_lwrite (hf , (LPSTR)lpTempImgData, BufSize);
_ LC perder(HF);
//Liberar memoria y recursos
ReleaseDC(hWnd, hDc );
desbloqueo local(htempmgdata);
local gratuito(htempmgdata);
desbloqueo global(himg data);
Devuelve VERDADERO
}
Código fuente corroído
Erosión del suelo (HWND hWnd, suelo Hori)
{
DWORD OffBits , BufSize
LPBITMAPINFOHEADER lpImgData
LPSTR lpPtr
HLOCAL hTempImgData
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpTempPtr p>
HDC hDc
HFILE hf
Long x, y;
Número de caracteres sin firmar;
int I;
//Para facilitar el procesamiento, todavía se usa la imagen en escala de grises de 256 niveles, pero solo se usan los elementos 0 y 255 de la paleta.
if(NumColors!=256){
MessageBox(hWnd, "¡Debe ser un mapa de bits monocromático con una paleta de escala de grises!",
"Mensaje de error" , MB_OK | MB_icon excepción);
Devuelve FALSE
}
off bits = BF off bits-sizeof (encabezado del archivo de mapa de bits);
//BufSize es el tamaño del búfer.
BufSize = off bits+bi . BIH height * line bytes;
//Asigna memoria para el nuevo búfer
if((htempmgdata = local alloc ( LHND, BufSize))==NULL)
{
MessageBox(hWnd, "¡Error al asignar memoria!", "Mensaje de error",
MB _ OK | MB_signo de exclamación);
Devolver FALSO
}
lpImgData =(LPBITMAPINFOHEADER)bloqueo global(himg data);
lpTempImgData = (LPBITMAPINFOHEADER)bloqueo local(htempmgdata);
//Copiar información del encabezado y datos de mapa de bits
memcpy(lpTempImgData, lpImgData, BufSize);
if(Hori )
{
//Realizar la operación de grabado horizontal.
for(y = 0; y & ltbi . BIH height; y++){
//lpPtr apunta a los datos originales, lpTempPtr apunta a los nuevos datos.
lpPtr =(char *)lpImgData+(BufSize-line bytes-y * line bytes)+1
lpTempPtr =(char *)lpTempImgData+
( BufSize-bytes de línea-y * bytes de línea)+1;
for(x = 1; x & ltbi . bi ancho-1; x++){
//Nota, para Para evitar que se salga de los límites, el rango de x es de 1 a -2.
num=(carácter sin firmar)* lpPtr
If (num==0){ //Debido a que los puntos negros están corroídos, solo se procesan los puntos negros.
*lpTempPtr=(unsigned char)0; //Primero configúrelo en punto negro
for(I = 0;i<3;i++){
num =(carácter sin firmar)*(lpPtr+I-1);
if(num==255){
//Si hay uno entre él y el vecino Si no lo es una mancha negra, simplemente déjala pudrirse.
//Grabado en puntos blancos
*lpTempPtr=(carácter sin firmar)255;
Rotura;
}
}
}
//La imagen original es blanca, pero la nueva imagen sigue siendo blanca.
else *lpTempPtr=(unsigned char)255;
//Señala el siguiente píxel
lpptr++;
lptempptr++;
}
}
}
De lo contrario{
//Realice la operación de grabado vertical.
for(y = 1; y & ltbi . BIH height-1; Y++){ //Tenga en cuenta que el rango de Y es la altura de 1 a -2 para evitar cruzar el límite.
//lpPtr apunta a los datos originales y lpTempPtr apunta a los nuevos datos.
lpPtr =(char *)lpImgData+(BufSize-línea bytes-y * línea bytes);
lpTempPtr =(char *)lpTempImgData+(BufSize-línea bytes-y * línea bytes); ) );
for(x = 0; x & ltbi.biWidthx++){
num=(carácter sin firmar)* lpPtr
If (num== 0){ //Debido a que los puntos negros están corroídos, solo se procesan los puntos negros.
*lpTempPtr=(unsigned char)0; //Primero configúrelo en punto negro
for(I = 0;i<3;i++){
num =(unsigned char)*(lpPtr+(I-1)* bytes de línea);
if(num==255){
//Si es él mismo y su vecino Si es uno de ellos No es una mancha negra, que se pudra.
//Grabado en puntos blancos
*lpTempPtr=(unsigned Character)255;
Rotura;
}
}
}
//La imagen original es blanca, pero la nueva imagen sigue siendo blanca.
else *lpTempPtr=(unsigned char)255;
//Señala el siguiente píxel
lpptr++;
lptempptr++;
}
}
}
if(hBitmap!=null)
eliminar objeto(mapa hbit) ;
hDc = GetDC(hWnd);
//Generar un nuevo mapa de bits
hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData,
(LONG)CBM_INIT,
(LPSTR)lpTempImgData+
tamaño de (BITMAPINFOHEADER)+
NumColors*tamaño de (RGBQUAD),
(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);
//Diferentes nombres de archivos de resultados.
if(Hori)
hf=_lcreat("c:\\herosion.bmp ", 0
Otros
); hf=_lcreat("c:\\verosion.bmp ", 0);
_lwrite(hf, (LPSTR)&bf, sizeof(encabezado del archivo de mapa de bits));
_lwrite (hf , (LPSTR)lpTempImgData, BufSize);
_ LC lost(HF);
//Liberar memoria y recursos
ReleaseDC(hWnd, hDc );
desbloqueo local(htempmgdata);
local gratuito(htempmgdata);
desbloqueo global(himg data);
Devuelve VERDADERO
}