openCV学习记录:滤镜:霓虹&曝光

霓虹滤镜

城市的夜晚,那闪烁的霓虹灯,想必大家都司空见惯了,给照片加上霓虹滤镜会不会很炫酷呢?
霓虹是用来描绘出图像的轮廓,勾画颜色变化的边缘,加强其过度效果,使图像产生轮廓发光的效果。

主要原理是:将当前像素与其同列正下方和右方的像素的RGB分量分别做梯度运算(差的平方和的平方根),运算结果作为当前的像素值。为了使图像轮廓边缘发光的效果更明显,可以适当地将运算结果乘以一个常数。
假设有1,2,3三个像素,1是当前点,2是1同行的下一个像素,3是1同列正下方的像素。三个点的RGB分量分别是(r1,g1,b1),(r2,g2,b2),(r3,g3,b3),R,G,B为计算后的结果,i 为常数那么转换公式如下:

  • R = i*sqrt( (r1-r2) * (r1-r2) + (r1-r3) * (r1-r3) )
  • G = i*sqrt( (g1-g2) * (g1-g2) + (g1-g3) * (g1-g3) )
  • B = i*sqrt( (b1-b2) * (b1-b2) + (b1-b3) * (b1-b3) )

RGB三个分量的值要控制在0~255之间。
完整代码如下:

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

using namespace cv;
using namespace std;

void niHongFilter(Mat &srcImage);

int main(){
    Mat srcImage = imread("lena.jpg");//图片在工程目录下,否则写绝对路径

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

    imshow("原图",srcImage);

    niHongFilter(srcImage);
    waitKey(0);
    return 0;
}

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

    for(int j = 0;j<rowNum-1;j++){
        uchar* data = srcImage.ptr<uchar>(j);
        for(int i = 0;i<colNum-1;i++){

            //当前像素的RGB分量
            int b1 = data[i*3];
            int g1 = data[i*3+1];
            int r1 = data[i*3+2];

            //同行下一个像素的RGB分量
            int b2 = data[(i+1)*3];
            int g2 = data[(i+1)*3+1];
            int r2 = data[(i+1)*3+2];

            //指针移到下一行
            data = srcImage.ptr<uchar>(j+1);

            //同列正下方的像素的RGB分量
            int b3 = data[i*3];
            int g3 = data[i*3+1];
            int r3 = data[i*3+2];

            //指针移回来
            data = srcImage.ptr<uchar>(j);

            //计算新的RGB分量的值
            int R = 10*sqrt((r1-r2)*(r1-r2) + (r1-r3)*(r1-r3));
            int G = 10*sqrt((g1-g2)*(g1-g2) + (g1-g3)*(g1-g3));
            int B = 10*sqrt((b1-b2)*(b1-b2) + (b1-b3)*(b1-b3));

            data[i*3] = max(0,min(B,255));;
            data[i*3+1] = max(0,min(G,255));;
            data[i*3+2] = max(0,min(R,255));;
        }
    }
    imshow("霓虹滤镜",srcImage);
}

常数取10的效果图:


这里写图片描述



曝光滤镜

曝光图像或多或少的损失了原图像中明快的颜色和色调。曝光滤镜主要原理是操作每个像素的RGB分量,若某个分量的值小于128,则用255减去这个值,把运算结果赋值给当前分量。
例如有个点像素值是(64,135,234),则运算后的值是(191,135,234)

完整代码如下:

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

using namespace cv;
using namespace std;

void baoGuangFilter(Mat &srcImage);

int main(){
    Mat srcImage = imread("lena.jpg");//图片在工程目录下,否则写绝对路径

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

    imshow("原图",srcImage);

    baoGuangFilter(srcImage);
    waitKey(0);
    return 0;
}

void baoGuangFilter(Mat &srcImage){
    int rowNum = srcImage.rows;
    int colNum = srcImage.cols * srcImage.channels();

    for(int j = 0;j<rowNum;j++){
        uchar* data = srcImage.ptr<uchar>(j);
        for(int i = 0;i<colNum;i++){
            data[i] = data[i] > 128 ? data[i] : 255 - data[i];
        }
    }

    imshow("曝光滤镜",srcImage);
}

效果图:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值