利用opencv进行简易的拍照并处理照片
今天用python写了一个调用摄像头拍照并对图片进行素描化或动漫化的小demo。
首先我的环境是:PyCharm+python3.8+opencv-python(4.4.0.42)
我们分析一下思路,第一步应该是调用我们的摄像头拍取照片并保存到一个文件夹,第二步是读取文件夹中的照片,把照片变成素描化或者动漫化。
下面就开始一步步实现:
第一步:
1.导入我们要用到的模块
#导入模块
import cv2
from PIL import Image, ImageOps, ImageFilter
2.初始化我们的摄像头
#摄像头
cap = cv2.VideoCapture(0)#这里如果你是默认的摄像头,那么就是0,否则你要取1
3.检测我们的摄像头是否在开启状态,并得到每一帧的图像效果;这里对照片每一帧的截取我用的是通过检测键盘按键来识别,如下:
num = 1
while(cap.isOpened()):#检测是否在开启状态
ret_flag,Vshow = cap.read()#得到每帧图像
cv2.imshow("Capture_Test",Vshow)#显示图像
k = cv2.waitKey(1) & 0xFF#按键判断
if k == ord('s'):#保存
cv2.imwrite('D:/MyShare/test_img/'+str(num)+".jpg",Vshow)#保存路径
print("success to save "+str(num)+".jpg")
print("-------------------------")
num += 1
elif k == ord(' '):#空格退出
break
4.根据上面的三步,我们就保存了我们摄像头截取的照片,那么我们不再使用摄像头就应该把摄像头关闭,防止它一直占用我们的资源同时也要释放内存。
#释放摄像头
cap.release()
#释放内存
cv2.destroyAllWindows()
这样我们就把第一步给完成了。
接下来,我们就来完成我们的第二步操作:
第二步:
1.编写把照片转成漫画风格的函数,里面用到了高斯金字塔取样,双边滤波,模糊,增强边缘效果。这些我们都可以去网上百度到,那么我们就不在这里进行讨论了,具体的参数是可以自己去调试的,我这里只给我的参数。那么直接上代码:
#转成漫画风格
def toCarttonStyle(picturePath):
#设置输入输出路径和文件名称
imgInput_FileName = picturePath
imgOutput_FileName = picturePath.split(".")[0] + '_cartoon.' + picturePath.split(".")[1]
# imgOutput_FileName = picturePath
#属性设置
num_down = 2 #缩减像素采样的数目
num_bilateral = 7 #定义双边滤波的数目
#读取图片
img_rgb = cv2.imread(imgInput_FileName)
#img_rgb = cv2.imdecode(np.fromfile(imgInput_FileName, dtype=np.uint8), cv2.IMREAD_COLOR)
#用高斯金字塔降低取样
img_color = img_rgb
for _ in range(num_down):
img_color = cv2.pyrDown(img_color)
#重复使用小的双边滤波代替一个大的滤波
for _ in range(num_bilateral):
img_color = cv2.bilateralFilter(img_color,d=9,sigmaColor=9,sigmaSpace=7)
#升采样图片到原始大小
for _ in range(num_down):
img_color = cv2.pyrUp(img_color)
#转换为灰度并且使其产生中等的模糊
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
img_blur = cv2.medianBlur(img_gray,7)
#检测到边缘并且增强其效果
img_edge = cv2.adaptiveThreshold(img_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,blockSize=9,C=2)
#算法处理后,照片的尺寸可能会不统一
#把照片的尺寸统一化
height = img_rgb.shape[0]
width = img_rgb.shape[1]
img_color = cv2.resize(img_color,(width,height))
# 转换回彩色图像
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
img_cartoon = cv2.bitwise_and(img_color, img_edge)
# 保存转换后的图片
cv2.imwrite(imgOutput_FileName, img_cartoon)
print('文件转换成漫画成功,保存在' + imgOutput_FileName)
2.把照片转成素描风格,这里我们肯定是要先把照片进行一个透明度转换,再接下来就是把照片的色彩改成灰色(你也可以改成你想要的颜色),然后再把照片进行模糊度的处理,就转成了简单的素描风格。
透明度转换:
#透明度转换,素描转换的一部分
def dodge(a,b,alpha):
#alpha为图片透明度
return min(int(a * 255 /(256 - b * alpha)),255)
图像转成素描:
#图片转换为素描
def toSketchStyle(picturePath,blur=25,alpha=1.0):
# 设置输入输出路径和文件名称
imgInput_FileName = picturePath
imgOutput_FileName = picturePath.split(".")[0] + '_Sketch.' + picturePath.split(".")[1]
# imgOutput_FileName = picturePath
#转化成ima对象
img = Image.open(picturePath)
#将文件转成灰色
img1 = img.convert('L')
img2 = img1.copy()
img2 = ImageOps.invert(img2)
#模糊度
for i in range(blur):
img2 = img2.filter(ImageFilter.BLUR)
width,height = img1.size
for x in range(width):
for y in range(height):
a = img1.getpixel((x,y))
b = img2.getpixel((x,y))
img1.putpixel((x,y),dodge(a,b,alpha))
#保存转换后文件
img1.save(imgOutput_FileName)
print('文件转换成漫画成功,保存在' + imgOutput_FileName)
这样就把第二步完成了。下面我把全部的代码展示出来:
#导入模块
import cv2
from PIL import Image, ImageOps, ImageFilter
def camera():
#摄像头
cap = cv2.VideoCapture(0)#这里如果你是默认的摄像头,那么就是0,否则你要取1
flag = 1
num = 1
while(cap.isOpened()):#检测是否在开启状态
ret_flag,Vshow = cap.read()#得到每帧图像
cv2.imshow("Capture_Test",Vshow)#显示图像
k = cv2.waitKey(1) & 0xFF#按键判断
if k == ord('s'):#保存
cv2.imwrite('D:/MyShare/test_img/'+str(num)+".jpg",Vshow)#保存路径
print("success to save "+str(num)+".jpg")
print("-------------------------")
num += 1
elif k == ord(' '):#空格退出
break
#释放摄像头
cap.release()
#释放内存
cv2.destroyAllWindows()
#转成漫画风格
def toCarttonStyle(picturePath):
#设置输入输出路径和文件名称
imgInput_FileName = picturePath
imgOutput_FileName = picturePath.split(".")[0] + '_cartoon.' + picturePath.split(".")[1]
# imgOutput_FileName = picturePath
#属性设置
num_down = 2 #缩减像素采样的数目
num_bilateral = 7 #定义双边滤波的数目
#读取图片
img_rgb = cv2.imread(imgInput_FileName)
#img_rgb = cv2.imdecode(np.fromfile(imgInput_FileName, dtype=np.uint8), cv2.IMREAD_COLOR)
#用高斯金字塔降低取样
img_color = img_rgb
for _ in range(num_down):
img_color = cv2.pyrDown(img_color)
#重复使用小的双边滤波代替一个大的滤波
for _ in range(num_bilateral):
img_color = cv2.bilateralFilter(img_color,d=9,sigmaColor=9,sigmaSpace=7)
#升采样图片到原始大小
for _ in range(num_down):
img_color = cv2.pyrUp(img_color)
#转换为灰度并且使其产生中等的模糊
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
img_blur = cv2.medianBlur(img_gray,7)
#检测到边缘并且增强其效果
img_edge = cv2.adaptiveThreshold(img_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,blockSize=9,C=2)
#算法处理后,照片的尺寸可能会不统一
#把照片的尺寸统一化
height = img_rgb.shape[0]
width = img_rgb.shape[1]
img_color = cv2.resize(img_color,(width,height))
# 转换回彩色图像
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
img_cartoon = cv2.bitwise_and(img_color, img_edge)
# 保存转换后的图片
cv2.imwrite(imgOutput_FileName, img_cartoon)
print('文件转换成漫画成功,保存在' + imgOutput_FileName)
#透明度转换,素描转换的一部分
def dodge(a,b,alpha):
#alpha为图片透明度
return min(int(a * 255 /(256 - b * alpha)),255)
#图片转换为素描
def toSketchStyle(picturePath,blur=25,alpha=1.0):
# 设置输入输出路径和文件名称
imgInput_FileName = picturePath
imgOutput_FileName = picturePath.split(".")[0] + '_Sketch.' + picturePath.split(".")[1]
# imgOutput_FileName = picturePath
#转化成ima对象
img = Image.open(picturePath)
#将文件转成灰色
img1 = img.convert('L')
img2 = img1.copy()
img2 = ImageOps.invert(img2)
#模糊度
for i in range(blur):
img2 = img2.filter(ImageFilter.BLUR)
width,height = img1.size
for x in range(width):
for y in range(height):
a = img1.getpixel((x,y))
b = img2.getpixel((x,y))
img1.putpixel((x,y),dodge(a,b,alpha))
#保存转换后文件
img1.save(imgOutput_FileName)
print('文件转换成漫画成功,保存在' + imgOutput_FileName)
if __name__ == '__main__':
camera()
imgInput_FileName = input('输入文件路径: ')
while True:
print('1、漫画风格')
print('2、素描风格')
userChoose = input('请选择风格(输入序号即可):')
if userChoose.__eq__('1'):
toCarttonStyle(imgInput_FileName)
break
elif userChoose.__eq__('2'):
toSketchStyle(imgInput_FileName)
break
else:
print('违法输入(请输入序号)')
break
我放一张运行的展示图:
运行成功以后,你就可以去你的文件夹看看照片了。
下面的链接是关于高斯金字塔,滤波和模糊度:
https://www.cnblogs.com/wj-1314/p/11981974.html
https://zhuanlan.zhihu.com/p/279602383
https://www.cnblogs.com/april0315/p/13716651.html
本人水平有限,如有错误,可以来纠正我,欢迎大家进行交流。
利用opencv进行简易的拍照并处理照片的更多相关文章
- c++开发ocx入门实践三--基于opencv的简易视频播发器ocx
原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/51404649 利用opencv做了个简易的视频播放器的ocx,可以在c++/c#/web ...
- 如何利用OpenCV自带的级联分类器训练程序训练分类器
介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...
- #利用openCV裁脸
#利用openCV裁脸import cv2 def draw_rects(img, rects): for x, y, w, h in rects: cv2.rectangle(img, (x, y) ...
- 利用OpenCV给图像添加中文标注
利用OpenCV给图像添加中文标注 : 参考:http://blog.sina.com.cn/s/blog_6bbd2dd101012dbh.html 和https://blog.csdn.net/ ...
- 利用opencv作透明重叠人群密度热度图
在作热度图的时候我们经常需要将热度图调整透明度后叠加在原图上达到更好的展示效果.比如检测人气密度的热度图: (来自sensetime) 一般作图的时候会第一时间想到matplotlib,因为可以很方便 ...
- 利用html5调用本地摄像头拍照上传图片[转]
利用html5调用本地摄像头拍照上传图片 html5概念啥的就不废话了,不知道的 百度, 谷歌一堆..今天学了学html5中的Canvas结合新增的<video>标签来获取本地摄像头, ...
- python利用opencv去除水印方法
OpenCV(Open Source Computer Vision Library)是一个跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法 在python中可以利用opencv来去除 ...
- 图像滑动窗口 利用opencv和matlab
1.利用opencv实现图像滑动窗口操作 功能:利用opencv实现图像滑动窗口操作(即利用已知尺寸的窗口遍历整幅图像,形成许多子图像) vs2015+opencv3.1 2016.10 函数实现 ...
- 利用opencv源代码和vs编程序训练分类器haartraining.cpp
如需转载请注明本博网址:http://blog.csdn.net/ding977921830/article/details/47733363. 一 训练框架 训练人脸检測分类器须要三个步骤: (1 ...
随机推荐
- pdb的插拔测试
pdb的插拔测试:将pdb从一个cdb中,插拔到另一个cdb中. 源端pdb unplug SQL> select instance_name from v$instance; INSTANCE ...
- Python小知识之对象的比较
好久不见 国庆回了趟老家,躺平了10天.作息时间基本和小学生差不多,8.9点就睡了, 那滋味别提多舒服了.时间也和小时候过得一样慢了...长时间不更新,还是不行滴,粉都快掉没了. 今天就结合日常生活的 ...
- AI 事件驱动场景 Serverless 实践
作者 | 李鹏(元毅) 来源 | Serverless 公众号 一.事件驱动框架:Knative Eventing 事件驱动是指事件在持续事务管理过程中,进行决策的一种策略.可以通过调动可用资源执行相 ...
- SpringCloud升级之路2020.0.x版-28.OpenFeign的生命周期-进行调用
本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 接下来,我们开始分析 OpenFeign 同步环境下的生命周期的第二部分,使用 Synch ...
- JVM:内存溢出OOM
JVM:内存溢出OOM 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 经典错误 JVM 中常见的两个 OOM 错误 StackoverflowError:栈溢出 ...
- BUAA2020软工团队beta得分总表
BUAA2020软工团队beta得分总表 [TOC] 零.团队博客目录及beta阶段各部分博客地址 团队博客 计划与设计博客 测试报告博客 发布声明博客 事后分析博客 敏 杰 开 发♂ https:/ ...
- [no code][scrum meeting] Beta 12
$( "#cnblogs_post_body" ).catalog() 例会时间:5月27日11:30,主持者:乔玺华 一.工作汇报 人员 昨日完成任务 明日要完成的任务 乔玺华 ...
- IRCUT作用
IRCUT组成原理 IRCUT由两层滤光片组成,一片红外截止或吸收滤光片和一片全透光谱滤光片 白天是红外截止滤光片工作,晚上是全透滤光片工作,白天摄像头可以接收到人眼无法识别的红外线,会导致图像与肉眼 ...
- Hash算法:双重散列
双重散列是线性开型寻址散列(开放寻址法)中的冲突解决技术.双重散列使用在发生冲突时将第二个散列函数应用于键的想法. 此算法使用: (hash1(key) + i * hash2(key)) % TAB ...
- MyBatis源码分析(八):设计模式
Mybatis中用到的设计模式 1. 建造者(Builder)模式: 表示一个类的构建与类的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一步一步创建一个复杂的对象,他只允许用户只通过指 ...