基於L0範數平滑的影象漫畫特效生成演算法
阿新 • • 發佈:2019-01-07
void* ImageCartoonStylizationThread(void *arg) { CartoonStylizationInfo *cartoonstylization_info = (CartoonStylizationInfo *)arg; BMPINFO *pSrcBitmap = cartoonstylization_info->pSrcBitmap; int block_count = cartoonstylization_info->block_count; int width = pSrcBitmap->lWidth; int height= pSrcBitmap->lHeight; int size = width*height; int mem_size = size * sizeof(double); double *rdata = (double *)malloc(mem_size); double *gdata = (double *)malloc(mem_size); double *bdata = (double *)malloc(mem_size); // 資料轉換 ConvertToDouble(pSrcBitmap, rdata, gdata, bdata); // 簡化細節 double *rgb_data[3] = { rdata, gdata, bdata }; L0ImageSmoothing(rgb_data, width, height, block_count, 0.01, 2.0); // 抽取邊緣 rdata = rgb_data[0]; gdata = rgb_data[1]; bdata = rgb_data[2]; double *gray_data = (double *)malloc(mem_size); double *hor_edgedata = (double *)malloc(mem_size); double *ver_edgedata = (double *)malloc(mem_size); for (int i = 0; i < size; i++) { gray_data[i] = (rdata[i]*0.299f + gdata[i]*0.587f + bdata[i]*0.114f); } EdgeDetectionFilter(gray_data, width, height, hor_edgedata, ver_edgedata); for (int i = 0; i < size; i++) { double edge_val = (fabs(hor_edgedata[i]) + fabs(ver_edgedata[i]))*1.2; edge_val = edge_val < 1.0 ? 1.0 - edge_val : 0.0; gray_data[i] = edge_val; } double *edge_data = (double *)malloc(mem_size); ExtractEdge(gray_data, edge_data, width, height, 15.7, 0.017, 75.5f); // 計算向量場 double *vec_x = (double *)malloc(mem_size); double *vec_y = (double *)malloc(mem_size); CalcVectorField(gray_data, width, height, vec_x, vec_y, 1.0); // 線積分卷積 LICFilter(edge_data, gray_data, vec_x, vec_y, width, height); free(vec_x); free(vec_y); vec_x = NULL; vec_y = NULL; free(edge_data); edge_data = NULL; // 結果合成 for (int i = 0; i < size; i++) { rdata[i] *= gray_data[i]; gdata[i] *= gray_data[i]; bdata[i] *= gray_data[i]; } // 資料轉換 ConvertToUchar(rdata, gdata, bdata, pSrcBitmap); // 效果微調 ImageAdjust(pSrcBitmap); free(gray_data); free(hor_edgedata); free(ver_edgedata); gray_data = NULL; hor_edgedata = NULL; ver_edgedata = NULL; free(rdata); free(gdata); free(bdata); rdata = NULL; gdata = NULL; bdata = NULL; return NULL; }