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