1. 程式人生 > >openCV學習記錄:濾鏡:霓虹&曝光

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);
}

效果圖:

這裡寫圖片描述