当前位置: 首页 > article >正文

[Computer Vision]实验一:图像的基本操作

目录

一、实验内容

二、实验代码

2.1 实验源码

2.2 实验结果


一、实验内容

  1. 分别使用PIL库和OpenCV库读取图像并实现可视化、调整图像大小、图像掩模等,对比OpenCV读取和PIL读取的差异;
  2. 绘制图像的轮廓与直方图;
  3. 实现图像的灰度变换、直方图均衡化;
  4. 实现图像的不同高斯模糊、计算导数;
  5. 形态学计数(计算圆形个数等)、去噪;
  6. 实现数字水印

二、实验代码

2.1 实验源码

2.1.1 PIL库、OpenCV库处理图像

def PIL_image(imgsrc):
    image=Image.open(imgsrc)
    image.show()
    width=500
    height=500
    new_size=(width,height)
    resized_image=image.resize(new_size)
    resized_image.show()
    mask=Image.new("L",image.size,0)
    draw=ImageDraw.Draw(mask)
    draw.rectangle([50,50,200,200],fill=255)
    result_img=Image.new("RGBA",image.size)
    result_img.paste(image,mask=mask)
    result_img.show()

    plt.figure("Original and new Images")
    plt.subplot(2,2,1)
    plt.imshow(image)
    plt.title("Original Image")
    plt.subplot(2,2,2)
    plt.imshow(resized_image)
    plt.title("Resized Image")
    plt.subplot(2,2,3)
    plt.imshow(result_img)
    plt.title("draw mask")
    plt.show()
def opencv_image(imgsrc):
    image=cv2.imread(imgsrc)
    cv2.imshow('img',image)
    width=320
    height=500
    new_size=(width,height)
    resized_image=cv2.resize(image,new_size,interpolation=cv2.INTER_AREA)
    cv2.imshow('resized img',resized_image)
    mask=np.zeros(image.shape[:2],dtype="uint8")
    cv2.rectangle(mask,(50,50),(200,200),255,-1)
    result_img=cv2.bitwise_and(image,image,mask=mask)
    cv2.imshow('draw mask',result_img)
    cv2.waitKey()
    cv2.destroyAllWindows()

    plt.figure("Original and new Images")
    plt.subplot(2,2,1)
    plt.imshow(image)
    plt.title("Original Image")
    plt.subplot(2,2,2)
    plt.imshow(resized_image)
    plt.title("Resized Image")
    plt.subplot(2,2,3)
    plt.imshow(result_img)
    plt.title("draw mask")
    plt.show()

2.1.2 绘制图像轮廓和灰度图

def drawoutlines(imgsrc):
    image=cv2.imread(imgsrc)
    gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    _,threshold=cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY)
    contours,_=cv2.findContours(threshold,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(image,contours,-1,(0,255,0),2)
    cv2.imshow('Image with Outlines',image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def draw_hist(imgsrc):
    image=cv2.imread(imgsrc)
    gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    histogram=cv2.calcHist([gray_img],[0],None,[256],[0,256])
    cv2.imshow('Original img',image)
    cv2.imshow('Gray img',gray_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    plt.figure()
    plt.title("draw histogram")
    plt.xlabel("Grayscale")
    plt.ylabel("pixel ")
    plt.plot(histogram)
    plt.xlim([0,256])
    plt.show()

2.1.3 直方图均衡化

def equlize_Hist(imgsrc):
    image=cv2.imread(imgsrc)
    gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    equ_img=cv2.equalizeHist(gray_img)
    histogram=cv2.calcHist([gray_img],[0],None,[256],[0,256])
    equa_hist=cv2.calcHist([equ_img],[0],None,[256],[0,256])
    cv2.imshow('Original img',image)
    cv2.imshow('Gray img',gray_img)
    cv2.imshow('EqualizeHist img',equ_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    plt.figure()
    plt.subplot(1,2,1)
    plt.title("Original histogram")
    plt.xlabel("Grayscale")
    plt.ylabel("pixel ")
    plt.plot(histogram)
    plt.xlim([0,256])
    plt.subplot(1,2,2)
    plt.title("EqualizedHist")
    plt.xlabel("Grayscale")
    plt.ylabel("pixel")
    plt.plot(equa_hist)
    plt.xlim([0,256])
    plt.show()

2.1.4 高斯模糊、计算导数

def Gauss_process(imgsrc):
    image=cv2.imread(imgsrc)
    Gauss_img=cv2.GaussianBlur(image,(7,7),0)
    x_sobel=cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3)
    x_sobel=cv2.convertScaleAbs(x_sobel)
    y_sobel=cv2.Sobel(image,cv2.CV_64F,0,1,ksize=3)
    y_sobel=cv2.convertScaleAbs(y_sobel)
    #magnitude=np.sqrt(np.square(x_sobel)+np.square(y_sobel))
    magnitude=np.sqrt(0.5*x_sobel+0.5*y_sobel)
    magnitude = np.uint8(magnitude)
    magnitude = np.uint8(cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX))
    print("x方向"+"\n"+str(x_sobel))
    print("y方向"+"\n"+str(y_sobel))
    print("梯度幅值"+"\n"+str(magnitude))
    cv2.imshow('Original Image',image)
    cv2.imshow('Blurred Image',Gauss_img)
    cv2.imshow('X',x_sobel)
    cv2.imshow('Y',y_sobel)
    cv2.imshow('XY',magnitude)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

2.1.5 心态学计数

def countcircles(imgsrc):
    min_radius=100
    max_radius=200
    image=cv2.imread(imgsrc)
    gray_img=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    Gauss_img=cv2.GaussianBlur(gray_img,(5,5),0)
    circles=cv2.HoughCircles(Gauss_img,cv2.HOUGH_GRADIENT,1,20,param1=40,param2=60,minRadius=min_radius,maxRadius=max_radius)
    if circles is not None:
        circles=np.uint16(np.around(circles))
        for i in circles[0,:]:
            cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)
            cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)
        cv2.imshow('circles image',image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        return len(circles[0,:])
    else:
        return 0

2.1.6数字水印

def add_watermark(imgsrc1,imgsrc2):
    image=cv2.imread(imgsrc1)
    watermark=cv2.imread(imgsrc2)
    watermark_alpha = 0.3
    image_with_watermark = cv2.addWeighted(image, 1 - watermark_alpha, watermark, watermark_alpha, 0)
    cv2.imshow('Image with Watermark', image_with_watermark)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

main函数

import cv2
from PIL import Image,ImageDraw
import matplotlib.pyplot as plt
import numpy as np  

if __name__ == '__main__':
    imgsrc="D:/Computer vision/picture1.png"
    imgsrc1="D:/Computer vision/picture3.png"
    imgsrc2="D:/Computer vision/picture2.png"
    imgsrc3="D:/Computer vision/picture4.png"
    PIL_image(imgsrc)
    opencv_image(imgsrc)
    drawoutlines(imgsrc1)
    draw_hist(imgsrc1)
    equlize_Hist(imgsrc)
    Gauss_process(imgsrc)
    count_cir=countcircles(imgsrc2) 
    print("图片中圆形个数:",count_cir)
    add_watermark(imgsrc1,imgsrc3)

2.2 实验结果

2.2.1  对比OpenCV读取和PIL读取的差异

(1)使用PIL库,通过使用Image.open()函数读取图像,通过image.show()实现可视化;通过Image.resize()函数调整图像大小;创建一个新RGBA图像,将原始图像粘贴到该图像上,同时应用mask(与原始图像大小相同的透明图像,图像中绘制了一个矩形区域)实现图像掩模。结果图如下:

图1 显示原图
图2 调整图像大小
图3 图像掩膜

(2)使用opencv库,通过cv2.imread()函数读取图像;通过cv2.imshow()函数实现可视化;通过cv2.resize()函数实现调整图像大小;通过cv2.bitwise_and()函数将原始图像与mask进行按位与操作实现图像掩模。结果图如下:

图4 显示原图
图5 调整图像大小
图6 图像掩膜

OpenCV读取的图像默认为NumPy数组,数据类型为uint8(无符号8位整数),范围从0到255。而PIL读取的图像默认为PIL.Image对象,数据类型为uint8。

2.2.2  使用opencv库绘制图像的轮廓和直方图的结果如下:

(1)绘制轮廓时,将读取的彩色图像转换为灰度图像,再应用阈值处理,将灰度图像转换为二值图像,使用cv2.findContours()函数在二值化图像中找到轮廓,只检测外部轮廓(cv2.RETR_EXTERNAL),并使用简化的方cv2.CHAIN_APPROX_SIMPLE来存储轮廓信息,结果存储在变量contours中。最后在原始图像上绘制轮廓并显示出来。

图7 绘制轮廓

 (2)绘制图像的直方图时,将彩色图像转换为灰度图像,通过cv2.calcHist()函数计算灰度图像的直方图,参数分别为:输入图像、通道列表、掩码、直方图的大小、灰度值的范围,再使用matplotlib.pyplot绘制直方图。

图8 绘制灰度直方图

2.2.3 实现图像灰度变换、直方图均衡化

将彩色图像转换为灰度图像,输出灰度直方图以及均衡化后的直方图。

图9  将彩色图像转换为灰度图像
图10 直方图均衡化

2.2.4 实现图像的不同高斯模糊、计算导数

通过使用cv2.GaussianBlur()函数对彩色图像image进行高斯模糊处理,其中,参数image是输入图像,参数(ksize,ksize)矩阵[代码中为(7,7)]为高斯核的大小,参数ksize为奇数,参数sigma为高斯核函数的标准差,当sigma为0时,opencv自动计算合适的标准差。

图11 高斯模糊
图12 计算导数

2.2.5  形态学计数(计算圆形个数)、去噪

通过min_radius和max_radius分别设置检测圆的最小半径和最大半径,其中min_radius=100,max_radius=200;将彩色图像转换为灰度图像,对灰度图像进行高斯模糊处理,以减少噪声,通过cv2.HoughCircles函数检测图像中的圆,其中,参数param1=40,param2=60;在原始图像上画出检测到的圆、圆心并显示、输出检测到圆的数量

图13 形态学计数

2.2.6  数字水印

通过读取两张图片,使用cv2.addWeighted()函数将水印图片添加到原图片上。这个函数的参数分别是:原图片、原图片的权重、水印图片、水印图片的权重(水印透明度)、可选的标量值(0)。最后显示带水印的图片。

图14 数字水印


http://www.kler.cn/a/509360.html

相关文章:

  • UI自动化测试:异常截图和page_source
  • FPGA车牌识别
  • K8S开启/关闭审计日志
  • 从零搭建SpringBoot3+Vue3前后端分离项目基座,中小项目可用
  • 2025 年 Java 最新学习资料与学习路线——从零基础到高手的成长之路
  • 异步 HTTP 请求
  • 挖掘机检测数据集,准确识别率91.0%,4327张原始图片,支持YOLO,COCO JSON,PASICAL VOC XML等多种格式标注
  • Java中的深拷贝与浅拷贝探究(利用反射+泛型实现深拷贝工具类)
  • iOS - Objective-C 底层实现中的哈希表
  • UiPath发送嵌入图片HTML邮件
  • BGP联盟
  • 窗口门狗实验(WWDG)实验【学习】
  • 【高阶数据结构】位图(BitMap)
  • OSPF - 路由过滤的几种方法
  • C++/QT环境下图像在窗口下等比例渲染绘制
  • OpenEuler学习笔记(一):常见命令
  • UDP 单播、多播、广播:原理、实践
  • 【C++笔记】红黑树封装map和set深度剖析
  • 高性能、并发安全的 Go 嵌入式缓存库 如何使用?
  • 浅谈云计算22 | Kubernetes容器编排引擎
  • ASP.NET Core全球化与本地化:打造多语言应用
  • vulnhub靶场【jangow】靶机,考察反弹shell的流量及端口的选择
  • Transformer之Encoder
  • 如何在openEuler中编译安装Apache HTTP Server并设置服务管理(含Systemd和Init脚本)
  • 【Linux】线程全解:概念、操作、互斥与同步机制、线程池实现
  • linux下springboot项目nohup日志或tomcat日志切割处理方案