OpenCV-Python实现怀旧滤镜与连环画滤镜
作者:一天一篇Python库 发布时间:2023-01-29 08:56:22
怀旧滤镜实现原理
不管是荣耀华为手机还是其他的手机,我们都可以找到相机中的怀旧效果,这是手机中常用的一种滤镜效果。
怀旧风格的设计主要是在图像的颜色空间进行处理。以BGR为例,对B、G、R这3个通道的颜色数值进行处理,让图像有一种泛黄的怀旧效果。设计的转换公式如下:
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通道的颜色,结果BGR是怀旧变换后的值。需要注意的是,颜色值的范围在[0,255],需要在程序中约束一下。
实现怀旧滤镜
既然我们已经了解了其实现的原理公式。下面我们直接上代码实现该功能,具体代码如下所示:
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()
运行之后,效果如下:
连环画滤镜原理
从怀旧滤镜就可以看出来,其实相机的各种滤镜效果就是对RGB的颜色通道进行计算处理。既然怀旧滤镜有公式,那么肯定的连环画滤镜也有公式。它的具体公式如下:
R = |g – b + g + r| * r / 256
G = |b – g + b + r| * r / 256
B = |b – g + b + r| * g / 256
实现连环画滤镜
有了公式,下面直接套用公式即可。具体代码如下所示:
# 连环画滤镜
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()
运行之后,效果如下:
综上所述,基本上所有的基础滤镜都是通过对RGB通道的颜色值进行公式计算得到的。当然,要是数学很好,又对算法情有独钟的读者,可以自己自研滤镜算法丰富滤镜的效果。
熔铸算法
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();
}
来源:https://liyuanjinglyj.blog.csdn.net/article/details/115118465


猜你喜欢
- 函数的参数:Python中函数定义非常简单,由于函数参数的存在,使函数变得非常灵活应用广泛;不但使得函数能够处理复杂多变的参数,还能简化函数
- 根据django官方文档建议,开发过程中会把生成的migrations提交到git中。由于各种原因,会有一些场景需要重置migrations
- 摘要: 当你想快速共享一个目录的时候,这是特别有用的,只需要1行代码即可实现。当你想快速共享一个目录的时候,这是特别有用的,只需
- 我就废话不多说了,大家还是直接看代码吧~print(np.shape(X))#(1920, 45, 20)X=sequence.pad_se
- 有如下的代码:class p1:def __init__(self,a,b):print("init in p1")se
- python实现超市扫码仪计费的程序主要是使用超市扫码仪扫商品的条形码,读取商品信息,实现计费功能。主要用到的技术是串口通信,数据库的操作,
- 很多DBA目前还停留在Oracle 9i或者10g,究其原因有可能是Oracle 11g的价格问题。本文将为大家讲解在Windows 7下安
- git cherry-pick可以选择某一个分支中的一个或几个commit(s)来进行操作。例如,假设我们有个稳定版本的分支,叫v2.0,另
- 1、公式推导 对幂律分布公式:对公式两边同时取以10为底的对数:所以对于幂律公式,对X,Y取对数后,在坐标轴上为线性方程。2、可视化 从图形
- pycharm指定python路径,pycharm配置python环境的方法是:1、依次点击【File】、【Project Interpre
- Python对于json数据键值对遍历Python中可以使用json模块来解析JSON格式的数据,将其转换成Python中的字典或者列表对象
- 前言JSON是一种轻量级的数据交换格式,采用了独立于语言的文本格式,类似XML,但是比XML简单,易读并且易编写。对机器来说易于解析和生成,
- php二分查找示例二分查找常用写法有递归和非递归,在寻找中值的时候,可以用插值法代替求中值法。当有序数组中的数据均匀递增时,采用插值方法可以
- 本文实例讲述了php中Array2xml类实现数组转化成XML的方法。分享给大家供大家参考。具体实现方法如下:<?phpclass A
- 我们需要将【小组销量排名表.xlsx】通过邮件发送给【组长邮箱.xlsx】中的各个组长。这里会学一个新的知识点—&
- 这些天安装 PyTorch,遇到了一些坑,特此总结一下,以免忘记。分享给大家。首先,安装环境是:操作系统 Win10,已经预先暗转了 Ana
- PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PHP ZIP 扩展已经开启,具体开
- 唉,可怜呀,用了这么久的SQL今天头一次用到外连接,效果不错,方法如下: 使用外联接 仅当至少有一个同属于两表的行符合联接条件时,内联接才返
- 实际上,无论是jupyter lab还是juputer notebook其工作目录都是对应在实际磁盘的某个区域的,可以使用%pwd命令进行查
- 本文实例讲述了Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法。分享给大家供大家参考,具体如下:#!/usr/bin