本文主要是介绍【OpenCV】Switching Eds: Face swapping,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Switching Eds: Face swapping with Python, dlib, and OpenCV
Face Swap using OpenCV ( C++ / Python )
肤色变换:
void specifiyHistogram(const cv::Mat source_image, cv::Mat target_image, cv::Mat mask)
{int source_hist_int[3][256];int target_hist_int[3][256];float source_histogram[3][256];float target_histogram[3][256];std::memset(source_hist_int, 0, sizeof(int) * 3 * 256);std::memset(target_hist_int, 0, sizeof(int) * 3 * 256);for (size_t i = 0; i < mask.rows; i++){auto current_mask_pixel = mask.row(i).data;auto current_source_pixel = source_image.row(i).data;auto current_target_pixel = target_image.row(i).data;for (size_t j = 0; j < mask.cols; j++){if (*current_mask_pixel != 0) {source_hist_int[0][*current_source_pixel]++;source_hist_int[1][*(current_source_pixel + 1)]++;source_hist_int[2][*(current_source_pixel + 2)]++;target_hist_int[0][*current_target_pixel]++;target_hist_int[1][*(current_target_pixel + 1)]++;target_hist_int[2][*(current_target_pixel + 2)]++;}// Advance to next pixelcurrent_source_pixel += 3;current_target_pixel += 3;current_mask_pixel++;}}// Calc CDFfor (size_t i = 1; i < 256; i++){source_hist_int[0][i] += source_hist_int[0][i - 1];source_hist_int[1][i] += source_hist_int[1][i - 1];source_hist_int[2][i] += source_hist_int[2][i - 1];target_hist_int[0][i] += target_hist_int[0][i - 1];target_hist_int[1][i] += target_hist_int[1][i - 1];target_hist_int[2][i] += target_hist_int[2][i - 1];}// Normalize CDFfor (size_t i = 0; i < 256; i++){source_histogram[0][i] = (source_hist_int[0][i] ? (float)source_hist_int[0][i] / source_hist_int[0][255] : 0);source_histogram[1][i] = (source_hist_int[1][i] ? (float)source_hist_int[1][i] / source_hist_int[1][255] : 0);source_histogram[2][i] = (source_hist_int[2][i] ? (float)source_hist_int[2][i] / source_hist_int[2][255] : 0);target_histogram[0][i] = (target_hist_int[0][i] ? (float)target_hist_int[0][i] / target_hist_int[0][255] : 0);target_histogram[1][i] = (target_hist_int[1][i] ? (float)target_hist_int[1][i] / target_hist_int[1][255] : 0);target_histogram[2][i] = (target_hist_int[2][i] ? (float)target_hist_int[2][i] / target_hist_int[2][255] : 0);}// Create lookup tableauto binary_search = [&](const float needle, const float haystack[]) -> uint8_t{uint8_t l = 0, r = 255, m;while (l < r){m = (l + r) / 2;if (needle > haystack[m])l = m + 1;elser = m - 1;}// TODO check closest valuereturn m;};uint8_t LUT[3][256];for (size_t i = 0; i < 256; i++){LUT[0][i] = binary_search(target_histogram[0][i], source_histogram[0]);LUT[1][i] = binary_search(target_histogram[1][i], source_histogram[1]);LUT[2][i] = binary_search(target_histogram[2][i], source_histogram[2]);}// repaint pixelsfor (size_t i = 0; i < mask.rows; i++){auto current_mask_pixel = mask.row(i).data;auto current_target_pixel = target_image.row(i).data;for (size_t j = 0; j < mask.cols; j++){if (*current_mask_pixel != 0){*current_target_pixel = LUT[0][*current_target_pixel];*(current_target_pixel + 1) = LUT[1][*(current_target_pixel + 1)];*(current_target_pixel + 2) = LUT[2][*(current_target_pixel + 2)];}// Advance to next pixelcurrent_target_pixel += 3;current_mask_pixel++;}}
}
这篇关于【OpenCV】Switching Eds: Face swapping的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!