openCV學習記錄:濾鏡:霓虹&曝光
阿新 • • 發佈:2019-01-01
霓虹濾鏡
城市的夜晚,那閃爍的霓虹燈,想必大家都司空見慣了,給照片加上霓虹濾鏡會不會很炫酷呢?
霓虹是用來描繪出影象的輪廓,勾畫顏色變化的邊緣,加強其過度效果,使影象產生輪廓發光的效果。
主要原理是:將當前畫素與其同列正下方和右方的畫素的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);
}
效果圖: