图像膨胀+滤波达到边缘外扩模糊效果

文章描述了在满足特定需求时,如何处理颜色渲染中出现的边界问题,通过膨胀和滤波技术改进原始数据的边界,以达到更平滑的渲染效果。作者使用OpenCV进行膨胀操作,并利用stb_image库实现滤波和重采样的算法优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个扯淡需求, 根据某些格网值渲染对应的颜色,  我们做的实现方案是按照色代码渐变做颜色映射, 但是某些厂家不顾结果正确性与否, 应是为了好看做的好看, 将边界膨胀模糊, 一个非风场,力场类似场数据做了一个类似场的渲染效果, 也不知道说啥好, 例如原始图渲染如下

经过一系列折腾最后只能做成如下下过了

 

 由于我们的边界和原始数据严格对应所以看起来有较多碎小区域,  不圆滑, 所以第一件事应该膨胀, 第二波用滤波重采样模糊下边界级别, 遂先用opencv验证():

 膨胀参数33, 再大无法看了

自行实现边界外扩一圈圈算法,效果如下,最后一幅没用中值滤波,因为太丑,换了高斯滤波:

 外扩主要算法如下:

 

//膨胀3*3
void expand(Buffer *SrcValueBuffer, int width, int height, double expend = 1, int kk = 3)
{
	Buffer k;
	k.AllocateT<Color>(width * height);
	k.Copy(SrcValueBuffer->BufferHead(), SrcValueBuffer->BufferSize());
	int m = kk;
	int n = kk;
	unsigned int * pSrcHead = (unsigned int*)(SrcValueBuffer->BufferHead());
	unsigned int * pDstHead = (unsigned int*)(k.BufferHead());

	int maskk = kk;
	int *maskkarry = new int[maskk];
	int maxdis = floor(maskk / 2.0);
	for (int i = 0; i < maskk; i++)
	{
		maskkarry[i] = 0 - maxdis + i; 
	}

	int maskm[3] = { -1,0,1 };
	int maskn[3] = { -1,0,1 };
	static Color nocolor = Color(0, 0, 0, 0);
	
	for (int i = 1; i < width - 1; i++)
	{
		Color* data = (Color*)(pSrcHead + i * height);
		Color* kdata = (Color*)(pDstHead + i * height);
		for (int j = 1; j < height - 1; j++)
		{
			Color col = *(data + j);
			if (col != nocolor)
				continue;

			int vagcount = 0;
			int R = 0, G = 0, B = 0, A = 0;

			for(int m=0; m < maskk; m++)
				for (int n = 0; n < maskk; n++)
				{
					Color col0 = *((Color*)(pSrcHead + (i + maskkarry[m]) * height) + (j + maskkarry[n]));
					if (col0 != nocolor)
					{
						R += col0.R;
						G += col0.G;
						B += col0.B;
						A += col0.A;
						vagcount++;
					}
				}
			if (vagcount <= 0)
				continue;
			*(kdata + j) = Color(R / vagcount,  G / vagcount, B / vagcount, A / vagcount);
			
		}
	}
	 SrcValueBuffer->Swap(k);
	 delete maskkarry;
}

 滤波就不写了,用stb_image库实现的,主要调用以下函数重采样

		float s0 = 0.; float t0 = 0; float s1 = 1.; float t1 = 1.; float *transform = 0;
		int channels = psrcdata->m_BandCount;
		int alpha_channel = -1;
		stbir_uint32 flags = 0;
		stbir_datatype type = TypeMapping(psrcdata->m_DataType);

		stbir_filter h_filter = ResampleFliter(rAlg);
		stbir_filter v_filter = ResampleFliter(rAlg);
		stbir_edge edge_horizontal = STBIR_EDGE_CLAMP;
		stbir_edge edge_vertical = STBIR_EDGE_CLAMP;
		//颜色空间
		stbir_colorspace colorspace = STBIR_COLORSPACE_LINEAR;

		stbir__resize_arbitrary(alloc_context,
			input_data, input_w, input_h, input_stride_in_bytes,
			output_data, output_w, output_h, output_stride_in_bytes,
			s0, t0, s1, t1, transform,
			channels, alpha_channel, flags, type,
			h_filter, v_filter,
			edge_horizontal, edge_vertical, colorspace) == 1;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值