edges = cv2.Canny(gray_blur, 200, 1500, apertureSize = 5)
时间: 2024-03-30 13:34:14 浏览: 216
这段代码使用OpenCV的函数cv2.Canny()来检测图像中的边缘。具体来说,它输入一个灰度图像gray_blur和两个阈值参数(lower_threshold和upper_threshold),然后使用Canny算法进行边缘检测并将结果存储在edges中。apertureSize参数是可选的,它指定了用于计算图像梯度的Sobel算子的大小。在这个例子中,它被设置为5。
相关问题
import cv2 import numpy as np # 加载图像 img = cv2.imread('color_blind_road_2.png') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 直线检测 edges = cv2.Canny(gray, 50, 150, apertureSize=3) lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=100, minLineLength=100, maxLineGap=10) for line in lines: x1, y1, x2, y2 = line[0] cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2) # 阈值分割 ret, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY) thresh = cv2.medianBlur(thresh, 5) # 彩色连续性空间分割 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) mask = cv2.inRange(h, 0, 20) | cv2.inRange(h, 160, 180) mask = cv2.bitwise_and(thresh, mask) # 纹理分割 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) texture = cv2.Canny(gray, 100, 200, apertureSize=3) texture = cv2.dilate(texture, None, iterations=3) texture = cv2.erode(texture, None, iterations=3) texture = cv2.bitwise_and(thresh, texture) # 显示结果 cv2.imshow('img', img) cv2.imshow('thresh', thresh) cv2.imshow('color', mask) cv2.imshow('texture', texture) cv2.waitKey(0) cv2.destroyAllWindows()改进代码
以下是对代码的一些改进建议:
1. 在 import 语句之间添加空格,使代码更易于阅读。
2. 使用函数封装代码,将不同的操作分别放入不同的函数中,可以使代码更加清晰和易于维护。
3. 添加异常处理,以避免因为文件路径或读取失败而导致程序崩溃。
4. 将一些常量或者需要调整的参数提取出来,以方便后续调整和修改。
5. 添加注释,以便代码的阅读和理解。
6. 使用 with 语句释放资源。
改进后的代码如下:
```python
import cv2
import numpy as np
def load_image(path):
"""加载图片"""
try:
img = cv2.imread(path)
return img
except Exception as e:
print(e)
return None
def gray_transform(img):
"""灰度转换"""
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return gray
def edge_detection(img, threshold1=50, threshold2=150, apertureSize=3):
"""边缘检测"""
edges = cv2.Canny(img, threshold1, threshold2, apertureSize=apertureSize)
return edges
def line_detection(img, edges, threshold=100, minLineLength=100, maxLineGap=10):
"""直线检测"""
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=threshold, minLineLength=minLineLength, maxLineGap=maxLineGap)
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
return img
def threshold_segmentation(img, threshold=150):
"""阈值分割"""
ret, thresh = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY)
thresh = cv2.medianBlur(thresh, 5)
return thresh
def hsv_segmentation(img, lower_range, upper_range):
"""HSV颜色空间分割"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_range, upper_range)
return mask
def color_segmentation(img, thresh, lower_range1=(0, 100, 100), upper_range1=(20, 255, 255), lower_range2=(160, 100, 100), upper_range2=(180, 255, 255)):
"""颜色分割"""
mask1 = hsv_segmentation(img, lower_range1, upper_range1)
mask2 = hsv_segmentation(img, lower_range2, upper_range2)
mask = cv2.bitwise_or(mask1, mask2)
mask = cv2.bitwise_and(thresh, mask)
return mask
def texture_segmentation(img, thresh, threshold1=100, threshold2=200, iterations=3):
"""纹理分割"""
gray = gray_transform(img)
texture = cv2.Canny(gray, threshold1, threshold2, apertureSize=3)
texture = cv2.dilate(texture, None, iterations=iterations)
texture = cv2.erode(texture, None, iterations=iterations)
texture = cv2.bitwise_and(thresh, texture)
return texture
def show_image(img, winname='image'):
"""显示图片"""
cv2.imshow(winname, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
# 加载图片
img = load_image('color_blind_road_2.png')
if img is None:
exit()
# 灰度转换
gray = gray_transform(img)
# 边缘检测
edges = edge_detection(gray)
# 直线检测
img = line_detection(img, edges)
# 阈值分割
thresh = threshold_segmentation(gray)
# 颜色分割
mask = color_segmentation(img, thresh)
# 纹理分割
texture = texture_segmentation(img, thresh)
# 显示结果
show_image(img, 'img')
show_image(thresh, 'thresh')
show_image(mask, 'color')
show_image(texture, 'texture')
```
import cv2 img = cv2.imread('test.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (3, 3), -5) edges_canny = cv2.Canny(blurred, 50, 150) # edges_thresh = cv2.adaptiveThreshold( # blurred, 255, # cv2.ADAPTIVE_THRESH_MEAN_C, # cv2.THRESH_BINARY_INV, 11, 2 # ) edges_thresh = cv2.adaptiveThreshold( blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2 ) combined = cv2.bitwise_and(edges_canny, edges_thresh) cv2.imshow("ART", combined) cv2.waitKey(0) 我要黑色线稿白色背景
这段代码是基于OpenCV库对图像进行边缘检测和自适应阈值处理,并尝试将两者的结果结合以创建一种类似于“线稿”的效果。为了确保最终结果是以**白色背景、黑色线条**的形式展示,我们需要特别关注两个方面:
1. **Canny 边缘检测** 的返回图像是黑白反转的(即默认为黑底白边),因此可以直接作为我们想要的线条部分;
2. 自适应二值化 `adaptiveThreshold` 使用了非反向二值化的设置 (`THRESH_BINARY`) ,这意味着对于原始较亮区域它会变成更暗的颜色,在这种情况下,需要保证该操作不会干扰到目标。
从您的描述来看,您希望得到的是白色的背景以及黑色轮廓的效果,这里需要注意几个点:
- Canny算子产生的边缘通常是黑色背景下有亮度变化的地方显示成白色,所以这一步已经接近于您所需要的形态,但如果您想进一步增强对比度可以考虑后续处理。
- 对于 `adaptiveThreshold` 函数,默认情况下生成的是黑色文字或物体(低灰度)位于白色背景上;但是由于你指定了 `cv2.THRESH_BINARY` 而不是 `cv2.THRESH_BINARY_INV` 参数,意味着输出将是深色前景浅色背景,这对于我们要达到的目标是有帮助的,因为我们可以利用这一点来做掩模操作。
然而,在最后组合两幅图片时使用了按位与运算(`bitwise_and`),这个选择可能会导致一些信息丢失,因为它只会保留两个输入数组中都存在的像素位置的数据,考虑到我们的目的是获取清晰可见的边界并且保持白色背景,建议改为按位或(`bitwise_or`)或者简单地相加再做归一化等其他方式来合并这两种特征提取的结果,同时也要检查每一步骤后的颜色模式是否符合预期。
此外,关于高斯模糊函数中的参数 `-5` 设置给第三个sigmaX参数是一个错误配置——通常应提供正值表示标准偏差大小,负数则会让系统自动计算一个合理的值出来,不过在这个例子里面更好的做法是指定具体的正数值如1或者直接设为零让API自行推断合适的宽度。
以下是调整后的参考代码片段,用于获得期望的黑白艺术风格效果图:
```python
import cv2
img = cv2.imread('test.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 更改高斯核尺寸及Sigma值以优化模糊程度
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
edges_canny = cv2.Canny(blurred, 50, 150)
# 确保自适应阈值处理采用正确的极性选项
edges_thresh = cv2.adaptiveThreshold(
blurred, 255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY_INV, # 这里改成INV使得输出为白底黑字形式
11, 2
)
# 改用按位或运算代替原来的按位与运算
combined = cv2.bitwise_or(edges_canny, edges_thresh)
# 或者简单的叠加并限制最大值为255也可以实现类似效果
# combined = np.clip((edges_canny + edges_thresh)/2, a_min=0,a_max=255).astype(np.uint8)
cv2.imshow("ART", combined)
cv2.waitKey(0)
```
阅读全文
相关推荐













