目錄
- 懷舊濾鏡實現(xiàn)原理
- 連環(huán)畫濾鏡原理
- 熔鑄算法
- 冰凍算法
懷舊濾鏡實現(xiàn)原理
不管是榮耀華為手機(jī)還是其他的手機(jī),我們都可以找到相機(jī)中的懷舊效果,這是手機(jī)中常用的一種濾鏡效果。
懷舊風(fēng)格的設(shè)計主要是在圖像的顏色空間進(jìn)行處理。以BGR為例,對B、G、R這3個通道的顏色數(shù)值進(jìn)行處理,讓圖像有一種泛黃的懷舊效果。設(shè)計的轉(zhuǎn)換公式如下:
B=0.272r+0.534g+0.131*b
G=0.349r+0.686g+0.168*b
R=0.393r+0.769g+0.189*b
計算公式中的小寫的bgr是原圖像的RGB通道的顏色,結(jié)果BGR是懷舊變換后的值。需要注意的是,顏色值的范圍在[0,255],需要在程序中約束一下。
實現(xiàn)懷舊濾鏡
既然我們已經(jīng)了解了其實現(xiàn)的原理公式。下面我們直接上代碼實現(xiàn)該功能,具體代碼如下所示:
def cowboy_effect(img):
new_img = img.copy()
h, w, n = img.shape
for i in range(w):
for j in range(h):
b = img[j, i, 0]
g = img[j, i, 1]
r = img[j, i, 2]
B = int(0.272 * r + 0.534 * g + 0.131 * b)
G = int(0.349 * r + 0.686 * g + 0.168 * b)
R = int(0.393 * r + 0.769 * g + 0.189 * b)
new_img[j, i, 0] = max(0, min(B, 255))
new_img[j, i, 1] = max(0, min(G, 255))
new_img[j, i, 2] = max(0, min(R, 255))
return new_img
if __name__ == "__main__":
img = cv2.imread("48.jpg")
cv2.imshow("0", img)
cv2.imshow("1", cowboy_effect(img))
cv2.waitKey()
cv2.destroyAllWindows()
運行之后,效果如下:
![](/d/20211017/c817b89be06c33aacc3723a2ac93d793.gif)
連環(huán)畫濾鏡原理
從懷舊濾鏡就可以看出來,其實相機(jī)的各種濾鏡效果就是對RGB的顏色通道進(jìn)行計算處理。既然懷舊濾鏡有公式,那么肯定的連環(huán)畫濾鏡也有公式。它的具體公式如下:
R = |g – b + g + r| * r / 256
G = |b – g + b + r| * r / 256
B = |b – g + b + r| * g / 256
實現(xiàn)連環(huán)畫濾鏡
有了公式,下面直接套用公式即可。具體代碼如下所示:
# 連環(huán)畫濾鏡
def comics_effect(img):
new_img = img.copy()
h, w, n = img.shape
for i in range(w):
for j in range(h):
b = img[j, i, 0]
g = img[j, i, 1]
r = img[j, i, 2]
R = int(int(abs(g - b + g + r)) * r / 256)
G = int(int(abs(b - g + b + r)) * r / 256)
B = int(int(abs(b - g + b + r)) * g / 256)
new_img[j, i, 0] = R
new_img[j, i, 1] = G
new_img[j, i, 2] = B
return new_img
if __name__ == "__main__":
img = cv2.imread("48.jpg")
cv2.imshow("0", img)
cv2.imshow("1", comics_effect(img))
cv2.waitKey()
cv2.destroyAllWindows()
運行之后,效果如下:
![](/d/20211017/92efede10affe872964e4c6b3f3f9ad4.gif)
綜上所述,基本上所有的基礎(chǔ)濾鏡都是通過對RGB通道的顏色值進(jìn)行公式計算得到的。當(dāng)然,要是數(shù)學(xué)很好,又對算法情有獨鐘的讀者,可以自己自研濾鏡算法豐富濾鏡的效果。
熔鑄算法
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;yheigh;y++)
{
uchar* imgP=img.ptruchar>(y);
uchar* dstP=dst.ptruchar>(y);
for (int x=0;xwidth;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 : (r0? 0 : r));
g = (g>255 ? 255 : (g0? 0 : g));
b = (b>255 ? 255 : (b0? 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;yheigh;y++)
{
uchar* imgP=img.ptruchar>(y);
uchar* dstP=dst.ptruchar>(y);
for (int x=0;xwidth;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 : (r0? -r : r));
g = (g>255 ? 255 : (g0? -g : g));
b = (b>255 ? 255 : (b0? -b : b));
// r = (r>255 ? 255 : (r0? 0 : r));
// g = (g>255 ? 255 : (g0? 0 : g));
// b = (b>255 ? 255 : (b0? 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();
}
到此這篇關(guān)于OpenCV-Python實現(xiàn)懷舊濾鏡與連環(huán)畫濾鏡的文章就介紹到這了,更多相關(guān)OpenCV 懷舊濾鏡與連環(huán)畫濾鏡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- python opencv圖像處理(素描、懷舊、光照、流年、濾鏡 原理及實現(xiàn))
- OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡特效
- Python OpenCV處理圖像之濾鏡和圖像運算
- OpenCV實現(xiàn)馬賽克和毛玻璃濾鏡效果