欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

opencv直方图,lomo,cartoon

发布时间:2023/12/16 编程问答 40 豆豆
生活随笔 收集整理的这篇文章主要介绍了 opencv直方图,lomo,cartoon 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

直方图绘制和直方图均衡化、局部直方图自适应均衡化
图像LOMO效果(暗处更暗,亮处更亮,产生光晕,虚焦)
图像cartoon效果

#include<opencv2/opencv.hpp> #include<iostream>using namespace std; using namespace cv;void lomo(string filename); void cartoon(string filename); void drawhist(string filename); int main() {drawhist("dsn.tif");lomo("dsn.tif");cartoon("dsn.tif");waitKey(0);return 0; }void drawhist(string filename) {Mat src = imread(filename);if (src.empty()) {return ;}vector<Mat> bgr;//0:blue,1:green,2:redsplit(src, bgr);Mat b, g, r;b = bgr[0];g = bgr[1];r = bgr.at(2);Mat hist_b, hist_g, hist_r;//存放直方图计算结果float range[] = { 0,256 };int histsize = 256;const float*ranges = { range };//直方图数值计算calcHist(&b, 1, 0, Mat(), hist_b, 1, &histsize, &ranges);calcHist(&g, 1, 0, Mat(), hist_g, 1, &histsize, &ranges);calcHist(&r, 1, 0, Mat(), hist_r, 1, &histsize, &ranges);//建画布int height = 300, width = 500;Mat histImg(height, width, CV_8UC3, Scalar(0, 0, 0));Mat histImg_b(height, width, CV_8UC3, Scalar(0, 0, 0));Mat histImg_g(height, width, CV_8UC3, Scalar(0, 0, 0));Mat histImg_r(height, width, CV_8UC3, Scalar(0, 0, 0));//归一化防溢出normalize(hist_b, hist_b, 0, histImg.rows, NORM_MINMAX, -1, Mat());normalize(hist_g, hist_g, 0, histImg.rows, NORM_MINMAX, -1, Mat());normalize(hist_r, hist_r, 0, histImg.rows, NORM_MINMAX, -1, Mat());int bin_w = cvRound((double)width / height);for (int i = 1; i < hist_b.rows; i++) {//Point q((i - 1)*bin_w, height - cvRound(hist_b.at<float>(i - 1, 0)));//Point h((i)*bin_w, height - cvRound(hist_b.at<float>(i,0)));//line(histImg, q, h, Scalar(255, 0, 0));//画线line(histImg_b, Point((i - 1)*bin_w, height - cvRound(hist_b.at<float>(i - 1, 0))), Point((i)*bin_w, height - cvRound(hist_b.at<float>(i, 0))),Scalar(255, 0, 0), bin_w);line(histImg_g, Point((i - 1)*bin_w, height - cvRound(hist_g.at<float>(i - 1, 0))), Point((i)*bin_w, height - cvRound(hist_g.at<float>(i, 0))),Scalar(0, 255, 0), bin_w);line(histImg_r, Point((i - 1)*bin_w, height - cvRound(hist_r.at<float>(i - 1, 0))), Point((i)*bin_w, height - cvRound(hist_r.at<float>(i, 0))),Scalar(0, 0, 255), bin_w);}histImg = histImg_b + histImg_g + histImg_r;//直方图均衡化和局部直方图自适应均衡化都需要的是当通道的图像Mat grayImg, dst;cvtColor(src, grayImg, COLOR_BGR2GRAY);//直方图均衡化equalizeHist(grayImg, dst);//局部直方图自适应均衡化//createCLAHE(clipLimit:颜色对比度的阈值,titleGridSize:进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡操作//1、实例化自适应直方图均衡化函数cv::Ptr<cv::CLAHE> clahe = createCLAHE(100, Size(10, 10));//2、进行自适应直方图均衡化Mat jubudst;clahe->apply(grayImg, jubudst);waitKey(0); }void lomo(string filename){Mat src = imread(filename);//Mat src = imread("lena.png");if (src.empty()) {return ;}//Mat src = Mat::zeros(Size(200, 200), CV_8UC3);//circle(src, Point(src.cols / 2, src.rows / 2), src.cols / 4, Scalar(255, 255, 255), -1);const double exponential_e = std::exp(1.0);Mat lut(1, 256, CV_8UC1);Mat result;//uchar* plut = lut.data;for (int i = 0; i < 256; i++) {double x = (double)(i / 256.0);//plut[i] = cvRound(256 * ( 1.0 / (1.0 + pow(exponential_e, -((x - 0.5) / 0.1))) ) );lut.at<uchar>(i) = cvRound(256 * (1 / (1 + pow(exponential_e, -((x - 0.5) / 0.1)))));//pow(InputArray src, double p, OutputArray dst)}//类似于根据新的计算公式,把原像素值 "映射" 到新像素值上去//2.分离通道std::vector<Mat> bgr;split(src, bgr);//3.调用LUT函数处理红色通道//也可以是蓝色,绿色cv::LUT(bgr[2], lut, bgr[2]);//cv::LUT(bgr[0], lut, bgr[0]);//cv::LUT(bgr[1], lut, bgr[1]);//4.合并通道cv::merge(bgr, result);//5.创建黑暗光环Mat halo(src.size(), CV_32FC3, Scalar(0.3, 0.3, 0.3));//这里画光环宽度应该是-1circle(halo, Point(src.cols / 2, src.rows / 2), src.cols / 3, Scalar(1, 1, 1), -1);//大模糊blur(halo, halo, Size(src.cols / 3, src.rows / 3));//6.将光环放到原图像上去,方法是将两个图像相乘(相乘必须是浮点型,所以需要类型转换)Mat resultf;result.convertTo(resultf, CV_32FC3);cv::multiply(resultf, halo, resultf);resultf.convertTo(result, CV_8UC3);waitKey(0); }void cartoon(string filename) {Mat src = imread(filename);//Mat src = imread("lena.png");if (src.empty()) {return;}Mat imgMedian;//1、中值滤波器去噪声,根据噪声特性medianBlur(src, imgMedian, 7);// Detect edges with canny//2、消除噪声后,用canny算子检测强边缘Mat imgCanny;Canny(imgMedian, imgCanny, 50, 150);// Dilate(膨胀) the edges使断续的边缘连接Mat kernel = getStructuringElement(MORPH_RECT, Size(2, 2));dilate(imgCanny, imgCanny, kernel);// Scale edges values to 1 and invert values//为防止乘法溢出,先将边缘图像整合到0-1区间imgCanny = imgCanny / 255;imgCanny = 1 - imgCanny;// Use float values to allow multiply between 0 and 1//3、乘法(将边缘图像加到原图像上(如lomo一样))Mat imgCannyf;imgCanny.convertTo(imgCannyf, CV_32FC3);// Blur the edgest to do smooth effect平滑边缘(小模糊)blur(imgCannyf, imgCannyf, Size(5, 5));/** COLOR **///颜色过滤// Apply bilateral filter to homogenizes color//为了得到卡通外观使用bilateralFilter双边滤波滤镜//一种滤波器,在保持边缘的同时降低图像的噪声,通过适当的参数(输入图像,输出图像,像素领域直径d,sigma色值,sigma坐标空间)Mat imgBF;bilateralFilter(src, imgBF, 9, 150.0, 150.0);//当直径(第三个参数)大于5的时候,bilateral开始变慢//当sigma的值大于150的时候,会出现卡通效果// truncate colors//为了更强大的卡通效果,通过乘除像素值将可能的颜色值截断为10Mat result = imgBF / 25;result = result * 25;/** MERGES COLOR + EDGES **/// Create a 3 channles for edges//必须合并颜色和边缘结果,然后创建一个三通道图像Mat imgCanny3c;Mat cannyChannels[] = { imgCannyf, imgCannyf, imgCannyf };merge(cannyChannels, 3, imgCanny3c);//合并// Convert color result to floatMat resultf;result.convertTo(resultf, CV_32FC3);// Multiply color and edges matricesmultiply(resultf, imgCanny3c, resultf);// convert to 8 bits colorresultf.convertTo(result, CV_8UC3);waitKey(0); }

总结

以上是生活随笔为你收集整理的opencv直方图,lomo,cartoon的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。