BS版图形系统 - OpenCV - 第4章笔记


QQ: 282397369

4 深入研究直方图和滤波器

4.1 技术要求

4.2 生成CMake脚本文件

4.3 创建图形用户界面

  • Show histogram
  • Equalize histogram
  • Lomography effect
  • Cartoonize effect
    在这里插入图片描述

4.4 绘制直方图

  • split
vector<Mat> bgr;		// 3个矩阵来处理每个输入图像通道
split(img, bgr);		// 划分成3个通道
int numbins = 256; 		// 定义直方图的区间数[每个可能的像素值对应一个区间]
float range[] = {0, 256};  // 定义变量范围
const float * histRange = {range}; 
Mat b_hist, g_hist, r_hist;	// 创建3个矩阵来存储每个直方图
calcHist( &bgr[0], 1, 0, Mat(), b_hist, 1, &numbins, &histRange );
calcHist( &bgr[1], 1, 0, Mat(), g_hist, 1, &numbins, &histRange );
calcHist( &bgr[2], 1, 0, Mat(), r_hist, 1, &numbins, &histRange );

Mat histImage( height, width, CV_8UC3, Scalar(20,20,20) );	// 准备绘制
normalize(b_hist, b_hist, 0, height,NORM_MINMAX );			// 标准化直方图矩阵[最大值与输出直方图图像的高度相同]
normalize(g_hist, g_hist, 0, height, NORM_MINMAX );
normalize(r_hist, r_hist, 0, height, NORM_MINMAX );


int binStep=cvRound((float)width/(float)numbins);
for( int i=1; i< numbins; i++)
{
   line( histImage, 
           Point( binStep*(i-1), height-cvRound(b_hist.at<float>(i-1) ) ),
           Point( binStep*(i), height-cvRound(b_hist.at<float>(i) ) ),
           Scalar(255,0,0)
       );
   line( histImage, 
           Point( binStep*(i-1), height-cvRound(g_hist.at<float>(i-1) ) ),
           Point( binStep*(i), height-cvRound(g_hist.at<float>(i) ) ),
           Scalar(0,255,0)
       );
   line( histImage, 
           Point( binStep*(i-1), height-cvRound(r_hist.at<float>(i-1) ) ),
           Point( binStep*(i), height-cvRound(r_hist.at<float>(i) ) ),
           Scalar(0,0,255)
       );
}

在这里插入图片描述

4.5 图像颜色均衡

为了均衡彩色图像,只需均衡亮度通道。可用HSV或YCrCb来分离亮度分量

    Mat ycrcb;
    cvtColor( img, ycrcb, COLOR_BGR2YCrCb);		// 将BGR图像转换为YCrCb

    // Split image into channels
    vector<Mat> channels;						// 分离YCrCb图像为不同的通道矩阵
    split( ycrcb, channels );
    
    // Equalize the Y channel only
    equalizeHist( channels[0], channels[0] );	// Y通道(0)为亮度,输入 -> 输出

    // Merge the result channels
    merge( channels, ycrcb );					// 合并成YCrCb

    // Convert color ycrcb to BGR
    cvtColor( ycrcb, result, COLOR_YCrCb2BGR );	// 转换为BGR格式

在这里插入图片描述

4.6 Lomography效果

  • Google相机、Instagram
  • LUT:查找表
  • 示例:仅用于红色通道、对图像应用暗晕来实现复古效果
  • 在这里插入图片描述
    示例中,取s=0.1。s越低越暗
    const double E = std::exp(1.0);
    // Create Lookup table for color curve effect
    Mat lut(1, 256, CV_8UC1);
    for (int i=0; i<256; i++)
    {
        float x= (float)i/256.0; 
        lut.at<uchar>(i)= cvRound( 256 * (1/(1 + pow(E, -((x-0.5)/0.1)) )) );
    }
   
    // Split the image channels and apply curve transform only to red channel
    vector<Mat> bgr;
    split(img, bgr);
    LUT(bgr[2], lut, bgr[2]);
    // merge result
    merge(bgr, result);
   
    // Create image for halo dark
    Mat halo( img.rows, img.cols, CV_32FC3, Scalar(0.3,0.3,0.3) );
    // Create circle 
    circle(halo, Point(img.cols/2, img.rows/2), img.cols/3, Scalar(1,1,1), -1); 
    blur(halo, halo, Size(img.cols/3, img.cols/3));
    
    // Convert the result to float to allow multiply by 1 factor
    Mat resultf;
    result.convertTo(resultf, CV_32FC3);
    
    // Multiply our result with halo
    multiply(resultf, halo, resultf);
    
    // convert to 8 bits
    resultf.convertTo(result, CV_8UC3);
    
    // show result
    imshow("Lomograpy", result);

    // Release mat memory
    halo.release();
    resultf.release();
    lut.release();
    bgr[0].release();
    bgr[1].release();
    bgr[2].release();

在这里插入图片描述

4.7 卡通效果

  • 边缘检测和颜色过滤

    Mat imgMedian;
    medianBlur(img, imgMedian, 7);			// 模糊,以便检测强边缘

    // Detect edges with 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
    imgCanny= imgCanny/255;					// 准备相乘,归一化后反转
    imgCanny= 1-imgCanny;
    
    // Use float values to allow multiply between 0 and 1
    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
    Mat imgBF;
    bilateralFilter(img, imgBF, 9, 150.0, 150.0);	// 采用双边滤波[保持边缘的同时降低图像的噪声],以获得卡通外观

    // truncate colors
    Mat 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 float 
    Mat resultf;
    result.convertTo(resultf, CV_32FC3);

    // Multiply color and edges matrices
    multiply(resultf, imgCanny3c, resultf);

    // convert to 8 bits color
    resultf.convertTo(result, CV_8UC3);
  • 模糊:高斯、中值…
  • 边缘:Canny过滤器检测强边缘
    在这里插入图片描述

4.8 总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值