功能函数
// 羽化 cv::Mat Eclosion(cv::Mat src, cv::Point center,float level) { if (level>0.9) level = 0.9f; float diff = (1-level) * (src.rows / 2 * src.rows / 2 + src.cols / 2 * src.cols / 2); cv::Mat result = src.clone(); for (int i = 0; i < result.rows; ++i) { for (int j = 0; j < result.cols; ++j) { float dx = float(center.x - j); float dy = float(center.y - i); float ra = dx * dx + dy * dy; float m = ((ra-diff) / diff * 255)>0? ((ra - diff) / diff * 255):0; int b = result.at<Vec3b>(i, j)[0]; int g = result.at<Vec3b>(i, j)[1]; int r = result.at<Vec3b>(i, j)[2]; b = (int)(b+ m); g = (int)(g + m); r = (int)(r + m); result.at<Vec3b>(i, j)[0] = (b > 255 ? 255 : (b < 0 ? 0 : b)); result.at<Vec3b>(i, j)[1] = (g > 255 ? 255 : (g < 0 ? 0 : g)); result.at<Vec3b>(i, j)[2] = (r > 255 ? 255 : (r < 0 ? 0 : r)); } } return result; }
测试代码
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; cv::Mat Eclosion(cv::Mat src, cv::Point center, float level); int main() { cv::Mat src = imread("test.jpg"); /*********** 羽化 ***********************/ cv::Mat eclosion1 = Eclosion(src, cv::Point(src.cols / 2, src.rows / 2), 0.5f); cv::Mat eclosion2 = Eclosion(src, cv::Point(src.cols / 2, src.rows / 2), 0.3f); imshow("原图", src); imshow("羽化1", eclosion1); imshow("羽化2", eclosion2); waitKey(0); return 0; } // 羽化 cv::Mat Eclosion(cv::Mat src, cv::Point center,float level) { if (level>0.9) level = 0.9f; float diff = (1-level) * (src.rows / 2 * src.rows / 2 + src.cols / 2 * src.cols / 2); cv::Mat result = src.clone(); for (int i = 0; i < result.rows; ++i) { for (int j = 0; j < result.cols; ++j) { float dx = float(center.x - j); float dy = float(center.y - i); float ra = dx * dx + dy * dy; float m = ((ra-diff) / diff * 255)>0? ((ra - diff) / diff * 255):0; int b = result.at<Vec3b>(i, j)[0]; int g = result.at<Vec3b>(i, j)[1]; int r = result.at<Vec3b>(i, j)[2]; b = (int)(b+ m); g = (int)(g + m); r = (int)(r + m); result.at<Vec3b>(i, j)[0] = (b > 255 ? 255 : (b < 0 ? 0 : b)); result.at<Vec3b>(i, j)[1] = (g > 255 ? 255 : (g < 0 ? 0 : g)); result.at<Vec3b>(i, j)[2] = (r > 255 ? 255 : (r < 0 ? 0 : r)); } } return result; }
测试效果
本文提供的PS羽化操作函数,可以实现类似PS中羽化的效果,即目标区域中心区不变,边缘区模糊化,center参数是羽化中心,level是羽化强度,该值越大则羽化程度越大,使整张图被羽化的区域变大~