有一个扯淡需求, 根据某些格网值渲染对应的颜色, 我们做的实现方案是按照色代码渐变做颜色映射, 但是某些厂家不顾结果正确性与否, 应是为了好看做的好看, 将边界膨胀模糊, 一个非风场,力场类似场数据做了一个类似场的渲染效果, 也不知道说啥好, 例如原始图渲染如下
经过一系列折腾最后只能做成如下下过了
由于我们的边界和原始数据严格对应所以看起来有较多碎小区域, 不圆滑, 所以第一件事应该膨胀, 第二波用滤波重采样模糊下边界级别, 遂先用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;