Opencv基础

opencv基础

一 参考教程:

二 图像基本操作

这个模块你将学习到::imshow(图片展示),imwrite(图片写入),imread(读取图片)

import cv2

_photo=cv2.imread("./saved_image.jpg")

if _photo is None:
    print("图片没有找到")

# cv2.imshow("display",_photo)
(h,w)=_photo.shape[:2]
# print((h,w))
# cv2.waitKey(0)#如果没有这一行,直接跑的话,你会发现窗口一闪而过

cv2.imwrite("saved_30.jpg",_photo,[cv2.IMWRITE_JPEG_QUALITY,30])

#笔者突然好奇jpeg压缩质量差别真的很大吗?如下实验:
#实验1:
_photo1=cv2.imread("saved_30.jpg")
#_rephoto=cv2.resize(_photo1,(w,h))#注意这个resize的(w,h)顺序时候shape返回顺序相反
result=cv2.subtract(_photo,_photo1)#发现相减之后全是黑色,但其实并不能说明两者就是相同(虽然哪怕视觉效果也不大明显)
#实验二:
diff=cv2.absdiff(_photo,_photo1)


# result=cv2.bitwise_or(_photo,_rephoto)
#result=cv2.addWeighted(_photo,0.7,_rephoto,0.3,0)
cv2.imshow("display",result)
cv2.imshow("diff",diff*10)
cv2.waitKey(0)
cv2.destroyAllWindows()

原图:![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7791da756c6a4081a9ddcfb7d1e61099.png)
diff跑出来的结果:
在这里插入图片描述

二.图像阈值处理

import cv2

_photo=cv2.imread("image.png")
#简单阀值处理
_hphoto=cv2.cvtColor(_photo,cv2.COLOR_BGR2GRAY)#变为灰度,因为黑白之间更容易分辨
ret,thresh2=cv2.threshold(_hphoto,100,255,cv2.THRESH_BINARY)

#自适应阀值处理
thresh1=cv2.adaptiveThreshold(_hphoto,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)#如果用photo会发现发现报错,因为photo是彩色

#二值化
ret1,thresh3=cv2.threshold(_hphoto,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow("Binary Threshold",thresh3)
cv2.waitKey(0)
cv2.destroyAllWindows()

声明:图片来自上述B站视频截图

1原始图片:

在这里插入图片描述

2简单阈值

在这里插入图片描述

3自适应阈值

在这里插入图片描述

二值化(适合双峰处理,黑白分明)

在这里插入图片描述
关于代码中各个函数参数的解释:

以下是转换为 Markdown 格式的内容:

图像二值化相关参数说明

一、自适应阈值处理(cv2.adaptiveThreshold

输入要求

  • _hphoto:输入图像,必须为单通道灰度图像(uint8 类型)。若输入彩色图像,需先用 cv2.cvtColor 转换为灰度图,否则会报错。

参数说明

  1. 255

    • 阈值最大值。超过阈值的像素值将设置为该值(即白色)。
  2. cv2.ADAPTIVE_THRESH_GAUSSIAN_C

    • 自适应阈值计算方法:
      • cv2.ADAPTIVE_THRESH_MEAN_C:使用邻域内像素的均值减去常量 C 作为阈值。
      • cv2.ADAPTIVE_THRESH_GAUSSIAN_C:使用邻域内像素的加权均值(权重为高斯分布减去常量 C 作为阈值。
  3. cv2.THRESH_BINARY

    • 阈值类型:
      • cv2.THRESH_BINARY:像素值 > 阈值时,设置为最大值(255);否则设置为 0
      • cv2.THRESH_BINARY_INV:与 cv2.THRESH_BINARY 逻辑相反(像素值 > 阈值时设为 0,否则设为 255)。
  4. 11

    • 邻域大小(blockSize):计算阈值的像素邻域大小,必须为奇数(如 357 等)。
      • 例:11 表示以每个像素为中心,取 11×11 的邻域计算阈值。
  5. 2

    • 常量 C:从计算出的阈值中减去的值,用于微调结果。
      • C > 0:阈值降低;C < 0:阈值升高。

简单的说就是把一个图片分成若干个区域,将每个区域取平均来计算

二、大津算法自动阈值处理(cv2.threshold + cv2.THRESH_OTSU

输入要求

  • _hphoto:输入图像,必须为单通道灰度图像(uint8 类型)。

参数说明

  1. 0
    • 固定阈值。当使用 cv2.THRESH_OTSU 时,此值会被忽略,OpenCV 自动计算最佳阈值。
  2. 255
    • 阈值最大值。超过阈值的像素值将设置为该值(即白色)。
  3. cv2.THRESH_BINARY + cv2.THRESH_OTSU
    • 阈值类型组合:
      • cv2.THRESH_BINARY:像素值 > 阈值时设为 255,否则设为 0
      • cv2.THRESH_OTSU:使用大津算法自动计算最佳阈值,适用于双峰图像(前景和背景像素值分布明显)。
  4. 返回值
    • ret1:自动计算出的最佳阈值(仅在使用 cv2.THRESH_OTSU 时返回)。
    • thresh3:二值化后的图像。

总结

  • 自适应阈值处理适用于局部光照不均匀的图像,通过邻域计算动态调整阈值。
  • 大津算法适用于全局光照均匀且前景/背景分布明显的图像,自动获取最优全局阈值。(前景后景的解释我也暂时还不理解,欢迎指教
四 平滑处理
import cv2

_photo=cv2.imread("./image.png")
blurred_img=cv2.blur(_photo,(5,5))#均值模糊
Gau_img=cv2.GaussianBlur(_photo,(5,5),0)#高斯模糊
comined_img=cv2.hconcat([_photo,blurred_img])#双边模糊

cv2.imshow("display",comined_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

首先算法作用是类似的,刚入门的时候还暂时做不到依照特定场景使用特定的方法(起码我是这样的

形象化理解(ai的解释,非常好,供参考):

1. 高斯模糊降噪(Gaussian Blur) 🌀

📌 费曼解释

高斯模糊就像戴上一副轻度磨砂的眼镜看图像——它通过加权平均周围像素来平滑图像,减少噪点(比如照片上的小颗粒)。

🔧 参数含义
blurred = cv2.GaussianBlur(gray, (5, 5), 0)  
  • (5, 5):高斯核的大小(宽度和高度),必须是正奇数(如3×3、5×5)。
    • 值越大,图像越模糊(比如(11,11)会更模糊)。
  • 0:标准差(SigmaX)。
    • 如果设为0,OpenCV会根据核大小自动计算。
    • 手动设置时,值越大,模糊效果越明显。
🌰 生活类比

想象用喷雾瓶在玻璃上喷水雾:

  • 核大小 = 喷雾的范围(喷得越广,玻璃越模糊)。
  • 标准差 = 喷雾的密度(喷得越密,模糊效果越均匀)。

2. 定义核(Kernel) ⬛

📌 费曼解释

核是一个小矩阵,像一把小刷子,在图像上滑动做数学运算。它决定了形态学操作(如腐蚀、膨胀)的效果范围。

🔧 代码示例
kernel = np.ones((3, 3), np.uint8)  # 3×3的全1矩阵  
  • (3, 3):核的尺寸。3×3表示每次处理3×3像素的区域。
  • np.uint8:数据类型(无符号8位整数)。
🌰 生活类比

核就像不同形状的印章:

  • np.ones((3,3))是一块方形印章,覆盖3×3区域。
  • 如果用cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)),会得到一个圆形印章。
五 形态学操作

形态学常用的操作:腐蚀(相当于用硫酸倒在纸上,主要视觉效果是让边缘部分变细);膨胀(顾名思义,边缘变粗);开运算和闭运算(我实验的图效果不太明显);梯度操作(可以看到明显的轮廓边缘)

import cv2
import numpy as np

# 读取图像
image = cv2.imread('image.png', 1)

# 定义结构元素
kernel = np.ones((10,10), np.uint8)

# 腐蚀操作
eroded_image = cv2.erode(image, kernel, iterations=1)#腐蚀
_oopen_morphology_imge=cv2.morphologyEx(image,cv2.MORPH_OPEN,kernel)#开运算
_close_morphlogy_image=cv2.morphologyEx(image,cv2.MORPH_CLOSE,kernel)#闭运算
dilate_image = cv2.dilate(image, kernel, iterations=1)#膨胀
_grand_morphlogy_image=cv2.morphologyEx(image,cv2.MORPH_GRADIENT,kernel)#形态学梯度


# 显示结果
cv2.imshow('Eroded Image', eroded_image)
cv2.imshow('open_',_oopen_morphology_imge)
cv2.imshow('_close',_close_morphlogy_image)
cv2.imshow('dilate',dilate_image)
cv2.imshow('_grand',_grand_morphlogy_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

关于梯度运算在边缘运算中的使用

import cv2
import numpy as np

# 读取图像
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 计算 x 方向的梯度
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)

# 计算 y 方向的梯度
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
#CV_64F什么意思
# 计算梯度幅值
sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2)
#combine起来为什么这么奇怪
# 显示结果
cv2.imshow('Sobel X', sobel_x)
cv2.imshow('Sobel Y', sobel_y)
cv2.imshow('Sobel Combined', sobel_combined)
cv2.waitKey(0)
cv2.destroyAllWindows()

沿着Y轴:
在这里插入图片描述

combine后:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值