利用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 ...
随机推荐
- NOIP 模拟六 考试总结
T1辣鸡 T1就搞得这莫不愉快.. 大致题意是给你几个矩形,矩形覆盖的点都标记上,每个矩形无重复部分,求满足(x,y) (x+1,y+1)都标记过的点对数,范围1e9. 看起来很牛的样子,我确实也被1 ...
- Redis的单线程架构
前言 在一定的策略下适度地初始化线程池的线程数有利于提高CPU的利用率,达到高效率地在同一段时间内处理多个任务,最佳的线程数量一般是 最佳线程数=(线程等待的时间与线程CPU执行时间之比+1)*CPU ...
- linux 测试2
.阅读目录●第一种:cat /dev/null > filename●第二种:: > filename●第三种:> filename●第四种:echo "" &g ...
- Serverless:这真的是未来吗?(二)
原文 | https://www.pulumi.com/blog/is_serverless_the_future_part_2/ 作者 | Lee Briggs & Piers Karsen ...
- go 连接MSSQLServer数据库【遇到的坑】
前言:项目测试需要用到mssqlserver数据库连接,遇到坑,自己爬直接上代码: package main import ( "database/sql" " ...
- ArcPy获取栅格属性
获取栅格属性 (数据管理) 描述 从元数据和栅格数据集的相关描述性统计数据中检索信息. 使用方法 返回的属性将显示在结果窗口中. 此工具的 Python 结果是地理处理结果对象.要获取字符串值,请使用 ...
- 时序数据库InfluxDB的基本语法
一 了解InfluxDB的必要性 时序数据库主要存放的数据 Time series data is a series of data points each associated with a spe ...
- 一个神秘的oj2587 你猜是不是dp(线段树优化建图)
哇 这难道不是happiness的翻版题嘛? 从\(S\)向一个点连染成白色的收益 从这个点向\(T\)连染成黑色的收益 对于额外的收益,建一个辅助点,跟区间内的每个点连\(inf\),然后向S/T, ...
- Winform同步调用异步函数死锁原因分析、为什么要用异步
1.前言 几年前,一个开发同学遇到同步调用异步函数出现死锁问题,导致UI界面假死.我解释了一堆,关于状态机.线程池.WindowsFormsSynchronizationContext.Post.co ...
- MyBatis 中实现SQL语句中in的操作 (11)
MyBatis 中实现SQL语句中in的操作 概括:应用myBatis实现SQL查询中IN的操作 1.数据库结构及其数据 2.mapper.xml文件 <?xml version="1 ...