學習OpenCV:濾鏡系列(10)——懷舊色 & 連環畫 & 熔鑄 & 冰凍
阿新 • • 發佈:2019-02-09
==============================================
版權所有:小熊不去實驗室CSDN部落格
==============================================
懷舊色調色原理
#include <opencv/cv.h> #include <opencv/highgui.h> using namespace cv; using namespace std; int main() { Mat src = imread("D:/scene04.jpg",1); int width=src.cols; int heigh=src.rows; RNG rng; Mat img(src.size(),CV_8UC3); for (int y=0; y<heigh; y++) { uchar* P0 = src.ptr<uchar>(y); uchar* P1 = img.ptr<uchar>(y); for (int x=0; x<width; x++) { float B=P0[3*x]; float G=P0[3*x+1]; float R=P0[3*x+2]; float newB=0.272*R+0.534*G+0.131*B; float newG=0.349*R+0.686*G+0.168*B; float newR=0.393*R+0.769*G+0.189*B; if(newB<0)newB=0; if(newB>255)newB=255; if(newG<0)newG=0; if(newG>255)newG=255; if(newR<0)newR=0; if(newR>255)newR=255; P1[3*x] = (uchar)newB; P1[3*x+1] = (uchar)newG; P1[3*x+2] = (uchar)newR; } } imshow("懷舊色",img); waitKey(); imwrite("D:/懷舊色.jpg",img); }
原圖:
懷舊色:
連環畫原理:
連環畫的效果與影象灰度化後的效果相似,它們都是灰度圖,但連環畫增大了影象的對比度,使整體明暗效果更強. 演算法:
R = |g – b + g + r| * r / 256
G = |b – g + b + r| * r / 256;
B = |b – g + b + r| * g / 256;
#include <math.h> #include <opencv/cv.h> #include <opencv/highgui.h> using namespace cv; using namespace std; int main() { Mat src = imread("D:/scene04.jpg",1); int width=src.cols; int heigh=src.rows; RNG rng; Mat img(src.size(),CV_8UC3); for (int y=0; y<heigh; y++) { uchar* P0 = src.ptr<uchar>(y); uchar* P1 = img.ptr<uchar>(y); for (int x=0; x<width; x++) { float B=P0[3*x]; float G=P0[3*x+1]; float R=P0[3*x+2]; float newB=abs(B-G+B+R)*G/256; float newG=abs(B-G+B+R)*R/256; float newR=abs(G-B+G+R)*R/256; if(newB<0)newB=0; if(newB>255)newB=255; if(newG<0)newG=0; if(newG>255)newG=255; if(newR<0)newR=0; if(newR>255)newR=255; P1[3*x] = (uchar)newB; P1[3*x+1] = (uchar)newG; P1[3*x+2] = (uchar)newR; } } Mat gray; cvtColor(img,gray,CV_BGR2GRAY); normalize(gray,gray,255,0,CV_MINMAX); imshow("連環畫",gray); waitKey(); imwrite("D:/連環畫.jpg",gray); }
連環畫效果:
熔鑄演算法
r = r*128/(g+b +1);
g = g*128/(r+b +1);
b = b*128/(g+r +1);
冰凍演算法
r = (r-g-b)*3/2;
g = (g-r-b)*3/2;
b = (b-g-r)*3/2;
#include <math.h> #include <opencv/cv.h> #include <opencv/highgui.h> #define MAXSIZE (32768) using namespace cv; using namespace std; void casting(const Mat& src) { Mat img; src.copyTo(img); int width=src.cols; int heigh=src.rows; Mat dst(img.size(),CV_8UC3); for (int y=0;y<heigh;y++) { uchar* imgP=img.ptr<uchar>(y); uchar* dstP=dst.ptr<uchar>(y); for (int x=0;x<width;x++) { float b0=imgP[3*x]; float g0=imgP[3*x+1]; float r0=imgP[3*x+2]; float b = b0*255/(g0+r0+1); float g = g0*255/(b0+r0+1); float r = r0*255/(g0+b0+1); r = (r>255 ? 255 : (r<0? 0 : r)); g = (g>255 ? 255 : (g<0? 0 : g)); b = (b>255 ? 255 : (b<0? 0 : b)); dstP[3*x] = (uchar)b; dstP[3*x+1] = (uchar)g; dstP[3*x+2] = (uchar)r; } } imshow("熔鑄",dst); imwrite("D:/img/熔鑄.jpg",dst); } void freezing(const Mat& src) { Mat img; src.copyTo(img); int width=src.cols; int heigh=src.rows; Mat dst(img.size(),CV_8UC3); for (int y=0;y<heigh;y++) { uchar* imgP=img.ptr<uchar>(y); uchar* dstP=dst.ptr<uchar>(y); for (int x=0;x<width;x++) { float b0=imgP[3*x]; float g0=imgP[3*x+1]; float r0=imgP[3*x+2]; float b = (b0-g0-r0)*3/2; float g = (g0-b0-r0)*3/2; float r = (r0-g0-b0)*3/2; r = (r>255 ? 255 : (r<0? -r : r)); g = (g>255 ? 255 : (g<0? -g : g)); b = (b>255 ? 255 : (b<0? -b : b)); // r = (r>255 ? 255 : (r<0? 0 : r)); // g = (g>255 ? 255 : (g<0? 0 : g)); // b = (b>255 ? 255 : (b<0? 0 : b)); dstP[3*x] = (uchar)b; dstP[3*x+1] = (uchar)g; dstP[3*x+2] = (uchar)r; } } imwrite("D:/img/冰凍.jpg",dst); } int main() { Mat src = imread("D:/img/scene04.jpg",1); imshow("src",src); casting(src); freezing(src); waitKey(); }
熔鑄:
冰凍: