当前位置:   article > 正文

openCV学习记录:滤镜:木刻&怀旧_opencv 滤镜算法

opencv 滤镜算法

木刻滤镜

木刻滤镜其实就是图像的二值化处理。图像的二值化处理就是将每个像素点的RGB分量值设成0或255。进行图像二值化之前,先将图像做灰度化处理,灰度化就是把每个像素点的RGB分量值设成一样大。图像的灰度化处理有三种方法:最大值法,平均法或权值法。

最大值法:顾名思义就是取RGB三个分量的最大值作为灰度值,即:gray=max(R,G,B),这种方法转化的灰度图亮度很高。

平均值法:就是取RGB三个分量的平均值作为灰度值,即:gray=(R+G+B)/ 3。这种方法产生的灰度图比较柔和。

权值法:对RGB三个分量按不同的比率取值的和作为灰度值。由于人眼对绿色最为敏感,红色次之,对蓝色的敏感性最低,因此将得到较易识别的灰度图像。一般得到的灰度图像效果最好。公式如下:
Gray = 0.30R + 0.59G + 0.11B 。

二值化就是在灰度图像的基础上,所有灰度值大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。公式如下:
gray = gray > 阀值 ? 255 : 0。为了实现木刻滤镜,阀值设成127.

openCV有专门的图像灰度化处理函数:cvtColor()

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
  • 1

参数说明:

  • src:输入图像
  • dst:输出图像
  • code:颜色空间转换码,这个值决定转换模式,要想将彩色图像转成灰度图像,这个值设成:CV_BGR2GRAY
  • dstCn:一般为0

这个函数可以将图像在RGB,HSV ,HLS,Gray等多种模式间互相转换,第三个参数决定以哪种模式转换。
用该函数对彩色图像灰度化以后,图像会由三通道变成一通道。
完整版代码如下:

void muKeFilter(Mat &srcImage){
    Mat dstImage = srcImage;
    cvtColor(dstImage,dstImage,CV_BGR2GRAY);

    int rowNum = dstImage.rows;//要处理的行数
    int colNum = dstImage.cols ;//要处理的列数

    for(int j = 0;j<rowNum;j++){
        uchar * row = dstImage.ptr<uchar>(j);
        for(int i = 0;i<colNum ;i++){
            row[i] = row[i]  > 127 ? 255:0;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

如果不用cvtColor()函数对彩色图像做灰度化预处理,直接用自己的代码对图像灰度化处理,像下面的代码:

int rowNum = srcImage.rows;//要处理的行数
int colNum = srcImage.cols ;//要处理的列数

for(int j = 0;j<rowNum;j++){
    uchar * row = srcImage.ptr<uchar>(j);
    for(int i = 0;i<colNum ;i++){
        int gray = (row[i*3] + row[i*3+1] + row[i*3+2])/3  > 127 ? 255:0;//二值化
        row[i*3] = gray;
        row[i*3+1] = gray;
        row[i*3+2] = gray;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这时候,图像还是三通道的。

openCV里有一个专门的二值化函数

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
  • 1

参数说明:

  • src: 输入图像,必须是单通道的
  • dst: 输出图像
  • thresh: 阀值
  • maxval: 最大值
  • type: 设定值的方法,有五种,如下图

    type

所以这个滤镜用最简单的方法写的话,代码很少,如下:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

void muKeFilter(Mat &srcImage);

int main(){
    Mat srcImage = imread("lena.jpg");

    if(!srcImage.data || srcImage.empty()){
        cout<<"读入图片错误!"<<endl;
        return -1;
    }

    imshow("原图",srcImage);

    muKeFilter(srcImage);

    waitKey(0);
    return 0;
}

 void muKeFilter(Mat &srcImage){
    Mat dstImage = srcImage;
    cvtColor(dstImage,dstImage,CV_BGR2GRAY);
    threshold(dstImage,dstImage,127,255,THRESH_BINARY);

    imshow("木刻滤镜",srcImage);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

效果图:
这里写图片描述

下面这篇文章介绍了四种二值化方法:
图像二值化

怀旧滤镜

怀旧滤镜就是让照片有种发黄的效果。主要算法思想:

按以下公式计算新的RGB值:

int R = 0.393*r + 0.769*g + 0.189*b;
int G = 0.349*r + 0.686*g + 0.168*b;
int B = 0.272*r + 0.534*g + 0.131*b;

RGB的值要约束在0与255之间。

主要代码如下:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

void huaiJiuFilter(Mat &srcImage);

int main(){
    Mat srcImage = imread("lena.jpg");

    if(!srcImage.data || srcImage.empty()){
        cout<<"读入图片错误!"<<endl;
        return -1;
    }

    imshow("原图",srcImage);

    huaiJiuFilter(srcImage);

    waitKey(0);
    return 0;
}

  void huaiJiuFilter(Mat &srcImage){
    int rowNum = srcImage.rows;
    int colNum = srcImage.cols;

    for(int j = 0;j<rowNum;j++){
        uchar* data = srcImage.ptr<uchar>(j);
        for(int i = 0;i<colNum;i++){
            int b = data[i*3];
            int g = data[i*3+1];
            int r = data[i*3+2];

            int R = static_cast<int>(0.393*r + 0.769*g + 0.189*b);
            int G = static_cast<int>(0.349*r + 0.686*g + 0.168*b);
            int B = static_cast<int>(0.272*r + 0.534*g + 0.131*b);

            data[i*3+2] = max(0,min(R,255));
            data[i*3+1] = max(0,min(G,255));
            data[i*3] = max(0,min(B,255));  
        }
    }

    imshow("怀旧滤镜",srcImage);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

效果图:

怀旧

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号