实现原理
图像形成颗粒感的效果,可以通过引入一个随机波动噪声实现,对图像三通道数据进行某个程度的调整,用level参数控制。直观看上去的效果,就是图像不再光滑,而是有点像素点状的感觉。
功能函数代码
// 颗粒感 cv::Mat Grainy(cv::Mat src, int level) { int row = src.rows; int col = src.cols; if (level > 50) level = 50; if (level < 0) level = 0; cv::Mat result = src.clone(); for (int i = 0; i < row; ++i) { uchar *t = result.ptr<uchar>(i); for (int j = 0; j < col; ++j) { for (int k = 0; k < 3; ++k) { int temp = t[3 * j + k]; temp += ((rand() % (2 * level)) - level); if (temp < 0)temp = 0; if (temp > 255)temp = 255; t[3 * j + k] = temp; } } } return result; }
C++测试代码
#include <iostream> #include <string> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; cv::Mat Grainy(cv::Mat src, int level); int main() { cv::Mat src = imread("dragon.jpg"); int level1 = 20,level2=50; cv::Mat result1 = Grainy(src, level1); cv::Mat result2 = Grainy(src, level2); cv::imshow("original", src); cv::imshow("result1", result1); cv::imshow("result2", result2); waitKey(0); return 0; } // 颗粒感 cv::Mat Grainy(cv::Mat src, int level) { int row = src.rows; int col = src.cols; if (level > 50) level = 50; if (level < 0) level = 0; cv::Mat result = src.clone(); for (int i = 0; i < row; ++i) { uchar *t = result.ptr<uchar>(i); for (int j = 0; j < col; ++j) { for (int k = 0; k < 3; ++k) { int temp = t[3 * j + k]; temp += ((rand() % (2 * level)) - level); if (temp < 0)temp = 0; if (temp > 255)temp = 255; t[3 * j + k] = temp; } } } return result; }
测试效果
图1 原图
图2 level为20的颗粒感
图3 level为50的颗粒感
适当地调整level,可以一定程度上增加图片的美感,营造出类似海报质感的效果。
如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!