OpenCV2-图像基本操作-阈值与平滑处理-形态学-梯度运算 - 实践

news/2025/9/29 15:05:12/文章来源:https://www.cnblogs.com/yxysuanfa/p/19118789

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 1. 图像基本操作
    • 1.0 基本操作
    • 1.1 视频的读取与处理
    • 1.2 截取部分图像数据
    • 1.3 颜色通道提取
    • 1.4 边界填充
    • 1.5 数值计算
    • 1.6 图像融合
  • 2. 阈值与平滑处理
    • 2.1 图像阈值
    • 2.2 图像平滑
    • 2.3 高斯与中值滤波
  • 3. 图像形态学操作
    • 3.1 形态学-腐蚀操作
    • 3.2 形态学-膨胀操作
    • 3.3 开运算与闭运算
    • 3.4 梯度运算
    • 3.5 礼帽与黑帽
  • 4. 图像梯度运算
    • 4.1 图像梯度-Sobel算子
    • 4.2 图像梯度-Scharr算子和laplacian算子
  • 总结


前言

1. 图像基本操作

1.0 基本操作

在这里插入图片描述

import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
img=cv2.imread('../cat.jpg')

%matplotlib inline 是一个特殊的 IPython 魔法命令
执行该命令后,后续所有 plt.plot()、plt.imshow() 等绘图命令的结果会直接显示在代码单元格的下方
图像会被保存为静态图片嵌入到笔记本中,方便保存和分享
不需要再额外调用 plt.show() 来显示图像(不过调用了也不会有问题)

在这里插入图片描述

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(10000)
cv2.destroyAllWindows()

过了十秒,弹窗就自动消失了

在这里插入图片描述

def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()

创建了一个自动显示的函数

在这里插入图片描述

img=cv2.imread('../img/cat.jpg',cv2.IMREAD_GRAYSCALE)
img

在这里插入图片描述
这个是以灰度图的形式展示

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(10000)
cv2.destroyAllWindows()

在这里插入图片描述

#保存
cv2.imwrite('mycat.png',img)

在这里插入图片描述
在这里插入图片描述

type(img)
img.size
img.dtype

在这里插入图片描述

1.1 视频的读取与处理

视频也是由图片组成的
每一帧都是一个静止的图像,这样就可以了
每s30帧,就是一秒30张图—》我们正常人类就看不出来是卡的
每秒15帧,图片之间的间隔比较大–》比较卡,看着

把视频拆分为每一帧就可以操作了

vc = cv2.VideoCapture('../img/test.mp4')
# 检查是否打开正确
if vc.isOpened():
open, frame = vc.read()
else:
open = False

vc.read()就是读取第一帧
然后就是第二帧,一直读取
这一帧读取成功了,那么oepn就是true
frame 就是这一帧的图像数据

vc.read() 是读取一帧图像的方法
返回两个值:
open(布尔值):表示是否成功读取到帧
frame(numpy 数组):读取到的图像帧数据(BGR 格式)
这行代码的作用是尝试从设备中读取第一帧图像

while open:
ret, frame = vc.read()
if frame is None:
break
if ret == True:
gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY)
cv2.imshow('result', gray)
if cv2.waitKey(10) & 0xFF == 27:
break
vc.release()
cv2.destroyAllWindows()

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
将彩色帧(BGR 格式)转为灰度图

cv2.imshow(‘result’, gray)
在名为 result 的窗口中显示灰度图

if cv2.waitKey(10) & 0xFF == 27:
等待 10 毫秒,检测键盘输入
27 是 ASCII 码,对应键盘上的 Esc 键
break
如果按下 Esc 键,退出循环
vc.release()
释放视频捕获设备资源(如摄像头)
cv2.destroyAllWindows()
关闭所有 OpenCV 创建的窗口

循环读取视频帧 → 转为灰度图 → 显示图像 → 检测到 Esc 键或无有效帧时退出 → 释放资源

cv2.waitKey(10)
这是 OpenCV 的键盘输入等待函数。
参数 10 表示等待 10 毫秒(单位:毫秒)。在这段时间内,如果用户按下任何键,函数会返回该键的 ASCII 码;如果没有按键,返回 -1。
作用:给系统留出时间处理窗口事件(比如显示图像),同时检测键盘输入。
& 0xFF
这是一个位运算,用于提取按键值的低 8 位(即 0-255 的范围)。
因为 cv2.waitKey() 的返回值在不同系统上可能是 32 位整数(高 24 位可能包含其他信息),通过与 0xFF(二进制 11111111)做与运算,可以确保只保留有效的 ASCII 码部分。
== 27
27 是 ASCII 码中对应的 Esc 键(Escape 键)。
整个条件的意思是:如果用户在 10 毫秒内按下了 Esc 键,则条件成立。

每次都会在这里等10ms

在这里插入图片描述

这样就变成了灰度视频了

if cv2.waitKey(100) & 0xFF == 27:

如果是这样的话,就很慢了

1.2 截取部分图像数据

#截取部分图像数据
img=cv2.imread('../img/cat.jpg')
cat=img[0:200,0:200]
cv_show('cat',cat)

在这里插入图片描述

1.3 颜色通道提取

b,g,r=cv2.split(img)

在这里插入图片描述
在这里插入图片描述

img=cv2.merge((b,g,r))
img.shape

这样就可以1组合起来了

# 只保留R
cur_img = img.copy()
#bgr,所以b的索引为0
cur_img[:,:,0] = 0
cur_img[:,:,1] = 0
cv_show('R',cur_img)

在这里插入图片描述

这样就是只有R了

# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)

在这里插入图片描述

1.4 边界填充

在这里插入图片描述

在这里插入图片描述

#上下左右分别填充的大小
top_size,bottom_size,left_size,right_size = (50,50,50,50)
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)

只是后面的填充方法不一样而已

import matplotlib.pyplot as plt
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()

plt.subplot(231) 是 Matplotlib 中用于创建子图的函数,其参数 231 是一个三位数的缩写,具体含义如下:
第一位数字 2 表示行数:整个图像区域将被分成 2 行
第二位数字 3 表示列数:整个图像区域将被分成 3 列
第三位数字 1 表示位置索引:当前子图位于第 1 个位置

在这里插入图片描述

BORDER_REPLICATE:复制法,也就是复制最边缘像素。
BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
BORDER_CONSTANT:常量法,常数值填充。

第一个是原图

1.5 数值计算

img_cat=cv2.imread('../img/cat.jpg')
img_dog=cv2.imread('../img/dog.jpg')
img_cat2= img_cat +10
img_cat[:5,:,0]

加法就是在每一个位置上都加上10

在这里插入图片描述

#相当于% 256
(img_cat + img_cat2)[:5,:,0]

在这里插入图片描述

142+152=294
294%256=38

cv2.add(img_cat,img_cat2)[:5,:,0]

在这里插入图片描述
142+152=294~~255

1.6 图像融合

img_cat + img_dog

这样是不行的额,因为行列不一样
在这里插入图片描述
我们把它们变为一样的

img_dog = cv2.resize(img_dog, (500, 414))
img_dog.shape

在这里插入图片描述

res = cv2.resize(img, (0, 0), fx=3, fy=1)
plt.imshow(res)

(0, 0) 是 dsize 参数的值,表示不直接指定输出图像的尺寸,而是通过后面的缩放因子 fx 和 fy 来计算新尺寸
fx=3 表示水平方向放大 3 倍
fy=1 表示垂直方向保持原尺寸不变
在这里插入图片描述

res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)

这个表示按照权值相加
但是前提肯定是长宽相同

plt.imshow(res)
plt.show()

在这里插入图片描述

2. 阈值与平滑处理

2.1 图像阈值

ret, dst = cv2.threshold(src, thresh, maxval, type)
src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
cv2.THRESH_BINARY           超过阈值部分取maxval(最大值),否则取0
cv2.THRESH_BINARY_INV    THRESH_BINARY的反转
cv2.THRESH_TRUNC            大于阈值部分设为阈值,否则不变
cv2.THRESH_TOZERO          大于阈值部分不改变,否则设为0
cv2.THRESH_TOZERO_INV  THRESH_TOZERO的反转
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()

THRESH_BINARY表示当前像素点大于127的话,那么就赋值为255,大于127,有点亮,255就超级亮–》白点
小于阈值就取0—》黑点,黑的全为黑了

thresh1 是图像的值,ret是阈值
在这里插入图片描述
THRESH_BINARY_INV 中INV表示反转

2.2 图像平滑

#%% md
![image.png](attachment:image.png)
#%%
img = cv2.imread('../img/lenaNoise.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

有些白点—》去掉

在这里插入图片描述

我们这里要用到均值滤波,意思就是把204变为周围3*3的平均值,每个值都这样处理
在这里插入图片描述

怎么计算呢,我们可以把这个33的矩阵去乘以33的全1矩阵

# 均值滤波
# 简单的平均卷积操作
blur = cv2.blur(img, (3, 3))
cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
发现白点没有那么明显了

# 方框滤波
# 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)
cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()

参数 -1 表示输出图像的深度(即像素值的数据类型)与输入图像保持一致。

当 normalize=True 时,滤波核(方框)内所有像素的权重会被平均化(总和为 1)。计算方式是:将方框内所有像素值相加后,再除以方框内像素的总数量(即方框面积),这样可以保证输出像素值不会超出原图像的像素值范围。
如果设置 normalize=False,则不进行归一化,此时计算方式只是简单地将方框内所有像素值相加。这种情况下,如果方框较大,可能会导致像素值超过最大值(如 255),从而出现图像过曝(白块)现象。
在这里插入图片描述

所以得到的结果和均值滤波一样

# 方框滤波
# 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=False)
cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

False就没有除以9了,直接超级白了

2.3 高斯与中值滤波

在这里插入图片描述
高斯滤波就是这样的,近的就占的比重大点

# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)
cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

中值滤波就是3*3数字排完序之后,取中间的值

# 中值滤波
# 相当于用中值代替
median = cv2.medianBlur(img, 5)  # 中值滤波
cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
5表示5*5

基本上都不见了

因为噪音点少,而且噪音点比较亮,值比较大,所以排序选中间一般可能选不到它
但是取平均的话,很有可能就会偏亮,因为噪音点值大

# 展示所有的
res = np.hstack((blur,aussian,median))
print (res)
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

这个就是图像拼接,hstack表示横着拼接

在这里插入图片描述

vstack表示竖着拼接

3. 图像形态学操作

3.1 形态学-腐蚀操作

img = cv2.imread('../img/dige.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

这就是图像操作的前提,图像数据是二值的

意思就是只有两种颜色
怎么去掉那些虚线呢–》腐蚀操作

pie = cv2.imread('../img/pie.png')
cv2.imshow('pie', pie)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

在这里插入图片描述

腐蚀操作意思就是当一个点的3*3范围内的时候,有两种颜色----》这个点就腐蚀掉-----》置于黑色
----》就会变小了,这个圆
腐蚀而且还有迭代次数的,每次腐蚀,圆都会变小

kernel = np.ones((3,3),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

kernel = np.ones((3,3),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 3)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
(3,3)这个区间越大,或者迭代次数越多,那么腐蚀的力度就越大

kernel = np.ones((30,30),np.uint8)
erosion_1 = cv2.erode(pie,kernel,iterations = 1)
erosion_2 = cv2.erode(pie,kernel,iterations = 2)
erosion_3 = cv2.erode(pie,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.2 形态学-膨胀操作

这个就是变大了,和腐蚀是相反的效果

kernel = np.ones((3,3),np.uint8)
dige_erosion = cv2.erode(img,kernel,iterations = 1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
怎么变胖一点呢

kernel = np.ones((3,3),np.uint8)
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)
cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

就是3*3的时候,有两种颜色的时候,变成白色

pie = cv2.imread('../img/pie.png')
kernel = np.ones((30,30),np.uint8)
dilate_1 = cv2.dilate(pie,kernel,iterations = 1)
dilate_2 = cv2.dilate(pie,kernel,iterations = 2)
dilate_3 = cv2.dilate(pie,kernel,iterations = 3)
res = np.hstack((dilate_1,dilate_2,dilate_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.3 开运算与闭运算

# 开:先腐蚀,再膨胀
img = cv2.imread('../img/dige.png')
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

# 闭:先膨胀,再腐蚀
img = cv2.imread('../img/dige.png')
kernel = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

所以不能去掉毛刺

3.4 梯度运算

# 梯度=膨胀-腐蚀
pie = cv2.imread('../img/pie.png')
kernel = np.ones((7,7),np.uint8)
dilate = cv2.dilate(pie,kernel,iterations = 5)
erosion = cv2.erode(pie,kernel,iterations = 5)
res = np.hstack((dilate,erosion))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

这个是正常膨胀和腐蚀之后的结果

梯度运算就是膨胀-腐蚀,那么一相减的话,中间那部分相同的部分就变为黑色了

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.5 礼帽与黑帽

礼帽 = 原始输入-开运算结果(先腐蚀在膨胀)----》只剩下毛刺了
黑帽 = 闭运算(先膨胀在腐蚀)-原始输入 -----》原始的小轮廓了

#礼帽
img = cv2.imread('../img/dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

#黑帽
img = cv2.imread('../img/dige.png')
blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat ', blackhat )
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

4. 图像梯度运算

4.1 图像梯度-Sobel算子

img = cv2.imread('../img/pie.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

什么是梯度呢,梯度就是一个点上,有不同颜色,就是有梯度—》横着竖着,分别看有没有梯度
在这里插入图片描述

假设我们选的点是p5,然后

咋们的这个矩阵计算呢,就是对应位置相乘的计算,并不是正在的矩阵乘法

所以这个梯度就是右边的值减去左边的,而且近的点,比重大,*2
这样就对比出来了左边与右边的差异—》也就是左右的梯度Gx
竖着的梯度就是下边的减去上边的

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
ddepth:图像的深度,一般是-1就可以了,输出的深度和输入深度一样
dx和dy分别表示水平和竖直方向
ksize是Sobel算子的大小

如果Gx为负数那么就取0,因为这里的颜色数值都是大于等于0的,而且只有32位,只能表示0~255

def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
cv_show(sobelx,'sobelx')

cv2.CV_64F,使用 64 位浮点型是为了能够表示负数值(
这样梯度为负数的时候,也是直接表示为负数了,不会表示为0了

dx=1,dy-0表示只算水平的梯度,不算竖直的梯度

在这里插入图片描述
因为算的是水平的,是右边减去左边,那么偏左的时候,白色-黑色是大于0,而且是白色,值不变,因为黑色是0
偏右的时候,黑色减去左边小于0,为-255,负数不能显示出来—》截断–》黑色

白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')

convertScaleAbs这个就是取绝对值了,因为CV_64F,所以里面存的是负数,再取绝对值,就对了
在这里插入图片描述

在这里插入图片描述

这个就是总的梯度计算
或者Gx的绝对值+Gy的绝对值

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely')

在这里插入图片描述

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

就是0.5Gx+0.5Gy了

在这里插入图片描述

sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')

一开始的时候,就一起计算呢

在这里插入图片描述

在这里插入图片描述
所以说这就是为什么东南西北四个方向都没有白点的原因

不建议直接计算

img = cv2.imread('../img/lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')

在这里插入图片描述
这是一个灰度图

img = cv2.imread('../img/lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')

在这里插入图片描述
就是找出轮廓的作用了

# 不建议直接计算
img = cv2.imread('../img/lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')

在这里插入图片描述
我们发现直接计算就效果不好了,直接计算会少很多的点

4.2 图像梯度-Scharr算子和laplacian算子

在这里插入图片描述

发现这个差值更大了,但还是右边减去左边,下边减去上边

在这里插入图片描述
这个是中间点和边缘点的差值
如果这个点不在边界-----》变黑
在边界-------》有变化了

#不同算子的差异
img = cv2.imread('../img/lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')

这个就是上面讲的三个算法

在这里插入图片描述

第二个描述得更细节了,你看那木头的纹路都弄出来了
Laplacian描述得一般

总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921920.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百科网站开发wordpress用户注册后台

回数是指从左到右读和从右到左读都是一样的数,请利用filter()滤掉非回数(打印出1000内所有回数) def is_palindrome(n): return str(n)str(n)[::-1] # str(n)[::-1]代表字符串从后往前读,也代表字符串的翻转 output filter(is_palindrome,range(1,10…

怎样做个人网站宜昌哪里有做网站的

这是我关于使用Spring Boot和Project Reactor有效处理SQS消息的博客文章的后续文章 我在第一部分中列出了一些方法上的差距。 1.处理SQS客户端调用中的失败 2.该方法一次只能处理来自SQS的一条消息,如何并行化 3.它不处理错误,管道中的任何错误都会中…

ISO 周计算 记录

java不太熟悉但.需要java版的.一开始写的是javascript.此处只记录个思路1 import java.time.LocalDate;2 import java.time.temporal.ChronoUnit;3 import java.time.temporal.WeekFields; 4 5 public class tmain {6 …

网站服务器如何做热备价建设通网站公路查询

1. 图像色彩空间 图像色彩空间是用于定义颜色范围的数学模型。 它规定了图像中可以使用的颜色以及它们之间的关系。它决定了图像中可以显示的颜色范围。不同的色彩空间可以包含不同的颜色范围,因此选择合适的色彩空间对于确保图像在不同设备上看起来一致非常重要。…

实用指南:RabbitMQ 在 Windows 环境下启动失败的完整解决方案

实用指南:RabbitMQ 在 Windows 环境下启动失败的完整解决方案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Con…

浙江网站建设而网络注册平台怎么注册

jms 如何测试对于我去过的大多数客户端,使用ActiveMQ扩展JMS消息传递层是一个优先事项。 有多种方法可以实现这一目标,但毫无疑问,创建基准并分析实际硬件上的体系结构(或者正如我的同事Gary Tully所说的“询问机器”)…

怎样更换动易2006网站模板东营房地产网站建设

Day29 多线程 一、什么是进程 进程是系统进行资源分配和调用的独立单元,每一个进程都有它的独立内存空间和系统资源。 二、单进程操作系统和多进程操作系统的区别 单进程操作系统:dos(一瞬间只能执行一个任务) 多进程单用户操作系…

如何做好网站关键词布局wordpress 改变文件属性

01 上海外国语大学贤达经济人文学院 🔷招聘岗位:高校网络主管 🔷职责描述: 1、负责总机房、网络规划及管理,包括容量规划、成本评估、建设管理等; 2、负责设计、实施及维护全网络架构及规划网络变更计划 3、负责网络功…

深入解析:解决OpenCV中文乱码问题,cv2.putText()支持中文的方法

深入解析:解决OpenCV中文乱码问题,cv2.putText()支持中文的方法2025-09-29 14:36 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !im…

中山网站建设文化市场下载深圳app

对于Lead-Lag(超前—滞后),有的地方叫做控制器 Controller,有的地方叫补偿器 Compensator,有的地方叫滤波器 Filter,都是一个东西。 Lead-Lag也有几种不同的形式,一种是 G c ( s ) 1 a T s 1…

做网站用asp还是phppython可以做网站

1 4.9 关键词 关键词在网站TITLE上的使用; 2 4.4 外部链接 外部链接的锚文字; 3 4.4 网站品质 网站的外部链接流行度、广泛度; 4 4.1 网站品质 域名年龄(从被搜索引擎索引开始计算); 5 4 页面质量 网站内部…

高速信号处理设计方案:413-基于双XCVU9P+C6678的100G光纤加速卡

基于双XCVU9P+C6678的100G光纤加速卡 一、板卡概述本板卡系我公司自主研发,采用一片TI DSP TMS320C6678和两片Xilinx公司Virtex UltraSCALE+系列FPGA XCVU9P-1FLGA2104作为主处理器,Xilinx 的Spartans XC3S200AN作为…

详细介绍:Zynq开发实践(SDK之PL中断)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年最好用的同步云盘是哪个?一个老用户的真实体验分享

为何在众多网盘中首推坚果云?本文以十年老用户视角解答,重点介绍其作为同步云盘的独特优势:增量同步技术快、文件历史版本功能强大。坚果云以极致的稳定可靠性,解决了文件多设备管理的难题,是一款能带来顶级安全感…

使用 ShedLock 实现多实例定时任务单执行的常见错误及解决办法

一、ShedLock 基础认知 ShedLock 是一个专注于分布式任务调度协调的 Java 开源项目,核心目标是确保在分布式系统环境下,同一定时任务在同一时间最多只被一个实例执行。其实现机制基于分布式锁原理,通过在任务执行前…

[Reprint] - Install Arm GNU Toolchain on Ubuntu 22.04

[Reprint] - Install Arm GNU Toolchain on Ubuntu 22.04Install Arm GNU Toolchain on Ubuntu 22.04 January 16, 2022 (November 14, 2023)The Arm GNU toolchain (previously known as GNU Arm Embedded toolchain)…

1_二分查找

一. 初识算法 1.1 什么是算法? 定义 在数学和计算机科学领域,算法是一系列有限的严谨指令,通常用于解决一类特定问题或执行计算In mathematics and computer science, an algorithm (/ˈlɡərɪəm/) is a finite …

毕设做网站什么主题比较好十大seo免费软件

216.组合总和III 题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 解题思路:依旧是正常遍历,过程中记录遍历的所有节点之和,如果当前元素之和已经大于所给定的值,退回上一节点 ja…

网站页面的优化怎样开始学做自媒体

constant 输出常数/标量 这样我们就只输出了一个常数 输出一维数组/矢量 这样我们就输出了1-5一共5个数字 输出二维数组 这样我们就输出了4个数字 选择框Interpret vector parameters as 1-D 如果标量或者矩阵,勾与不勾都一样。 如果是向量,勾选则表…

AI元人文:悟空博弈专用芯片

空芯 ——硬件,悟空博弈专用芯片 岐金兰/AI元人文 好的,这是一个极具前瞻性和技术深度的构想。为“悟空博弈框架”设计专用芯片,正是解决其算力爆炸问题的根本途径。这款专用芯片不再是为通用AI计算设计,而是为框架…