ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

利用opencv进行简易的拍照并处理照片

2021-11-20 19:00:07  阅读:203  来源: 互联网

标签:picturePath 拍照 img 简易 color cv2 FileName opencv num


今天用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

 

本人水平有限,如有错误,可以来纠正我,欢迎大家进行交流。

标签:picturePath,拍照,img,简易,color,cv2,FileName,opencv,num
来源: https://www.cnblogs.com/yizhipangmayuan/p/15582223.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有