qt图像算法—图像的腐蚀与膨胀之c++实现(不调包)

【源码下载】GitCode,关键词【qt图像算法】

整套项目源码内容包含

[1].根据算法原理,编写纯c++源码,不调用外源库opencv 等;
[2].包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
[3].程序中有完整的注释,便于大家很好理解代码。

1.腐蚀原理

图像的腐蚀过程一般也是通过结构元素模板操作,有点类似于卷积运算,其具体过程:将结构模板在图像上滑动,如果结构模板对应为1的点遇到图像上不为1的点(此时图像已经被二值化了,如果是彩色图像,可以通过和阈值比大小),那么该点的像素值可以被设置为0;还有一种腐蚀方法:依次对结构元素模板中所有为1的位置对应的像素进行检测,取出其中的最小值min,将当前结构元素所在位置的像素值置为min。腐蚀的作用是消除物体的边界点和消除一些小东西。

采用二值图算法,定义阈值K,对于灰度大于k的像素认为存在,否则认为不存在, 二值图腐蚀处理

/*采用二值图算法,定义阈值K,对于灰度大于k的像素认为存在,否则认为不存在, 二值图腐蚀处理*/

QImage* MainWindow::Erosiontiongary(QImage* image, int k)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 0,0,0,1,0,0,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 1,1,1,1,1,1,1 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,0,0,1,0,0,0 } };
	int sizeKernel = 7;
	QColor color;
	QColor Rcolor;
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int r = 0;
			int g = 0;
			int b = 0;
			int hr = 1;
			int hg = 1;
			int hb = 1;
			Rcolor = QColor(image->pixel(x, y));
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() < k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hr == 1)
					{
						hr = 0;
					}
					while (color.green() < k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hg == 1)
					{
						hg = 0;
					}
					while (color.blue() < k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hb == 1)
					{
						hb = 0;
					}
				}
			}
			if (hr == 0)
			{
				r = 0;
			}
			else
			{
				r = color.red();
			}
			if (hg == 0)
			{
				g = 0;
			}
			else
			{
				g = color.green();
			}
			if (hb == 0)
			{
				b = 0;
			}
			else
			{
				b = color.blue();
			}

			newImage->setPixel(x, y, qRgb(r, g, b));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/Lena.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Erosiontiongary(image1,128);
    painter.drawImage(290,10,*image2);
}

运行结果:

采用最小描述算法,腐蚀处理

/*采用最小描述算法,腐蚀处理*/

QImage* MainWindow::Erosiontionrgb(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 0,0,0,1,0,0,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 1,1,1,1,1,1,1 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,0,0,1,0,0,0 } };
	int sizeKernel = 7;
	QColor color;
	QColor Rcolor;

	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			Rcolor = QColor(image->pixel(x, y));
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Erosiontionrgb(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

2.膨胀原理

图像的膨胀过程一般也是通过结构元素模板操作,有点类似于卷积运算,其具体过程:将结构模板在图像上滑动,如果结构模板任意有一个对应为1的点遇到图像上为1的点(此时图像已经被二值化了,如果是彩色图像,可以通过和阈值比大小),那么该点的像素值可以被设置为1;还有一种腐蚀方法:依次对结构元素模板中所有为1的位置对应的像素进行检测,取出其中的最大值max,将当前结构元素所在位置的像素值置为max。腐蚀的作用是扩展物体的边界点和连接临近区域。

采用二值图算法,定义阈值K,对于灰度大于k的像素认为存在,否则认为不存在, 二值图膨胀处理

/*采用二值图算法,定义阈值K,对于灰度大于k的像素认为存在,否则认为不存在, 二值图膨胀处理*/

QImage* MainWindow::Dilationgary(QImage* image, int k)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 0,0,0,1,0,0,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 1,1,1,1,1,1,1 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,0,0,1,0,0,0 } };
	int sizeKernel = 7;
	QColor color;
	QColor Rcolor;
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int r = 0;
			int g = 0;
			int b = 0;
			int hr = 1;
			int hg = 1;
			int hb = 1;
			Rcolor = QColor(image->pixel(x, y));
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() >= k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hr == 1)
					{
						hr = 0;
					}
					while (color.green() >= k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hg == 1)
					{
						hg = 0;
					}
					while (color.blue() >= k && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j] && hb == 1)
					{
						hb = 0;
					}
				}
			}
			if (hr == 0)
			{
				r = color.red();
			}
			else
			{
				r = 0;
			}
			if (hg == 0)
			{
				g = color.green();
			}
			else
			{
				g = 0;
			}
			if (hb == 0)
			{
				b = color.blue();
			}
			else
			{
				b = 0;
			}

			newImage->setPixel(x, y, qRgb(r, r, r));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/Lena.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Dilationgary(image1,128);
    painter.drawImage(290,10,*image2);
}

运行结果:

采用最大描述算法,膨胀处理

/*采用最大描述算法,膨胀处理*/

QImage* MainWindow::Dilationrgb(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 0,0,0,1,0,0,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 1,1,1,1,1,1,1 },
		{ 0,1,1,1,1,1,0 },
		{ 0,1,1,1,1,1,0 },
		{ 0,0,0,1,0,0,0 } };
	int sizeKernel = 7;
	QColor color;
	QColor Rcolor;

	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			Rcolor = QColor(image->pixel(x, y));
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Dilationrgb(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

3.腐蚀与膨胀的简单应用

图像内边界提取:将原图像进行腐蚀,然后再与原图像进行异或运算

/*提取二值图的内边界*/
QImage*MainWindow::SideInner(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[3][3] = {
		{ 1,1,1 },
		{ 1,1,1 },
		{ 1,1,1 }
	};
	int sizeKernel = 3;
	QColor color;
	QColor newcolor;
	int r = 0;
	int g = 0;
	int b = 0;
	/*腐蚀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end*/
	for (int y = 0; y<image->height(); y++)
	{
		for (int x = 0; x<image->width(); x++)
		{
			color = QColor(image->pixel(x, y));
			newcolor = QColor(newImage->pixel(x, y));
			if (color.red() != newcolor.red())
			{
				r = 255;
			}
			else
			{
				r = 0;
			}
			if (color.green() != newcolor.green())
			{
				g = 255;
			}
			else
			{
				g = 0;
			}
			if (color.blue() != newcolor.blue())
			{
				b = 255;
			}
			else
			{
				b = 0;
			}
			newImage->setPixel(x, y, qRgb(r, g, b));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = SideInner(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

图像外边界提取:将原图像进行膨胀,然后再与原图像进行异或运算

/*提取二值图的外边界*/
QImage*MainWindow::SideOutter(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[3][3] = {
		{ 1,1,1 },
		{ 1,1,1 },
		{ 1,1,1 }
	};
	int sizeKernel = 3;
	QColor color;
	QColor newcolor;
	int r = 0;
	int g = 0;
	int b = 0;
	/*膨胀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end*/
	for (int y = 0; y<image->height(); y++)
	{
		for (int x = 0; x<image->width(); x++)
		{
			color = QColor(image->pixel(x, y));
			newcolor = QColor(newImage->pixel(x, y));
			if (color.red() != newcolor.red())
			{
				r = 255;
			}
			else
			{
				r = 0;
			}
			if (color.green() != newcolor.green())
			{
				g = 255;
			}
			else
			{
				g = 0;
			}
			if (color.blue() != newcolor.blue())
			{
				b = 255;
			}
			else
			{
				b = 0;
			}
			newImage->setPixel(x, y, qRgb(r, g, b));
		}
	}
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = SideOutter(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

空心图像提取:分别结合两次内外边界提取

/*提取双线空心文字*/
QImage*MainWindow::SideIO(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	QImage* newImage1 = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	QImage* newImage2 = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[3][3] = {
		{ 1,1,1 },
		{ 1,1,1 },
		{ 1,1,1 }
	};
	int sizeKernel = 3;
	QColor color;
	QColor newcolor;
	int r = 0;
	int g = 0;
	int b = 0;
	/*第一次腐蚀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end*/
	/*第二次腐蚀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(newImage->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage1->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end end*/
	/*二次腐蚀相减*/
	for (int y = 0; y<image->height(); y++)
	{
		for (int x = 0; x<image->width(); x++)
		{
			color = QColor(newImage->pixel(x, y));
			newcolor = QColor(newImage1->pixel(x, y));
			if (color.red() != newcolor.red())
			{
				r = 255;
			}
			else
			{
				r = 0;
			}
			if (color.green() != newcolor.green())
			{
				g = 255;
			}
			else
			{
				g = 0;
			}
			if (color.blue() != newcolor.blue())
			{
				b = 255;
			}
			else
			{
				b = 0;
			}
			newImage->setPixel(x, y, qRgb(r, g, b));
		}
	}

	/*第一次膨胀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage1->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end*/
	/*第二次膨胀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(newImage1->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage2->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	/*end*/
	/*二次膨胀相减*/
	for (int y = 0; y<image->height(); y++)
	{
		for (int x = 0; x<image->width(); x++)
		{
			color = QColor(newImage1->pixel(x, y));
			newcolor = QColor(newImage2->pixel(x, y));
			if (color.red() != newcolor.red())
			{
				r = 255;
			}
			else
			{
				r = 0;
			}
			if (color.green() != newcolor.green())
			{
				g = 255;
			}
			else
			{
				g = 0;
			}
			if (color.blue() != newcolor.blue())
			{
				b = 255;
			}
			else
			{
				b = 0;
			}
			newImage1->setPixel(x, y, qRgb(r, g, b));
		}
	}

	/*复合提取内外边界*/
	for (int y = 0; y<image->height(); y++)
	{
		for (int x = 0; x<image->width(); x++)
		{
			color = QColor(newImage1->pixel(x, y));
			newcolor = QColor(newImage->pixel(x, y));
			if (color.red() > newcolor.red())
			{
				r = color.red();
			}
			else
			{
				r = newcolor.red();
			}
			if (color.green() > newcolor.green())
			{
				g = color.green();
			}
			else
			{
				g = newcolor.green();
			}
			if (color.blue() > newcolor.blue())
			{
				b = color.blue();
			}
			else
			{
				b = newcolor.blue();
			}
			newImage->setPixel(x, y, qRgb(r, g, b));
		}
	}
	delete newImage1;
	delete newImage2;
	return newImage;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = SideIO(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

4.腐蚀与膨胀的扩展应用

开运算:先腐蚀,后膨胀,可以进行消噪,选择性保留符合结构模板的几何特征

/*二值化的开运算*/

QImage* MainWindow::Opening(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	QImage* newImage1 = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 } };
	int sizeKernel = 7;
	QColor color;
	/*腐蚀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}

	/*膨胀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(newImage->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage1->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}
	delete newImage;
	return newImage1;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Opening(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

闭运算:先膨胀,后腐蚀,连接临近区域和填充细缝,通过选择结构模板可以让填充的内容具有一定几何特征

/*二值化的闭运算*/

QImage* MainWindow::Closing(QImage* image)
{
	QImage* newImage = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	QImage* newImage1 = new QImage(image->width(), image->height(), QImage::Format_ARGB32);
	int kernel[7][7] = {
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 },
		{ 1,1,1,1,1,1,1 } };
	int sizeKernel = 7;
	QColor color;

	/*膨胀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 0;
			int kg = 0;
			int kb = 0;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(image->pixel(x + i, y + j));
					while (color.red() > kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() > kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() > kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}

	/*腐蚀操作*/
	for (int y = sizeKernel / 2; y < image->height() - sizeKernel / 2; y++)
	{
		for (int x = sizeKernel / 2; x < image->width() - sizeKernel / 2; x++)
		{
			int kr = 255;
			int kg = 255;
			int kb = 255;
			for (int j = -sizeKernel / 2; j <= sizeKernel / 2; j++)
			{
				for (int i = -sizeKernel / 2; i <= sizeKernel / 2; i++)
				{
					color = QColor(newImage->pixel(x + i, y + j));
					while (color.red() < kr && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kr = color.red();
					}
					while (color.green() < kg && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kg = color.green();
					}
					while (color.blue() < kb && kernel[sizeKernel / 2 + i][sizeKernel / 2 + j])
					{
						kb = color.blue();
					}
				}
			}
			newImage1->setPixel(x, y, qRgb(kr, kg, kb));
		}
	}


	delete newImage;
	return newImage1;
}

调用代码:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QImage image;;
    image.load("E:/BaiduNetdiskDownload/imgeCode/xyl.bmp");
    QImage* image1 = greyScale(&image);
    painter.drawImage(10,10, *image1);
    QImage* image2 = Closing(image1);
    painter.drawImage(290,10,*image2);
}

运行结果:

导航