OpenCV的简单练习

发布于:2024-12-18 ⋅ 阅读:(45) ⋅ 点赞:(0)

1、读取一张彩色图像并将其转换为灰度图。

import matplotlib.pyplot as plt

img = plt.imread("./flower.png")
# 灰度化
img_gray = img[:,:,0]*0.299 + img[:,:,1]*0.587 + img[:,:,2]*0.114

plt.subplot(121)
plt.imshow(img)
plt.subplot(122)
plt.imshow(img_gray,cmap='gray')
plt.tight_layout()
plt.show()

2、编写程序,读取一张彩色图像【flower.png】,将其转换为灰度图,然后进行二值化处理。接着,对二值化后的图像执行腐蚀和膨胀操作,并显示处理前后的图像。

import cv2

# 读取图像
img = cv2.imread("./flower.png")

# 调整图片大小为400x400像素
img = cv2.resize(img, (400,400))

# 将图像从BGR颜色空间转换为灰度图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 自适应阈值二值化
# 对灰度图像进行自适应二值化处理,以增强图像处理效果
img_adaptive_binary = cv2.adaptiveThreshold(img_gray,      # 参数1:输入的灰度图像
                                            255,  # 参数2: 二值化处理后的最大值
                                            cv2.ADAPTIVE_THRESH_GAUSSIAN_C,     # 参数3: 使用局部均值作为阈值计算方法
                                            cv2.THRESH_BINARY_INV,        # 参数4: 使用二值化阈值处理方式
                                            7,           # 参数5: 邻域大小,用于计算阈值的区域范围
                                            5)    # 参数6: 常数C,计算阈值时从均值中减去的值

# 创建椭圆形结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
# 腐蚀图像
img_erode = cv2.erode(img_adaptive_binary,kernel)
# 先腐蚀后膨胀图像
img_erode_dilate = cv2.dilate(img_erode,kernel)

# 显示腐蚀后的图像
cv2.imshow("img_erode",img_erode)
# 显示自适应二值化后的图像
cv2.imshow("img_adaptive_binary",img_adaptive_binary)
# 显示先腐蚀后膨胀的图像
cv2.imshow("img_erode_dilate",img_erode_dilate)
# 等待按键按下
cv2.waitKey(0)

3、编写程序,读取一张彩色图像,执行以下操作:

  1. 将图像缩放至指定大小(例如,宽度和高度都缩小为原来的一半)。
  2. 对缩放后的图像应用仿射变换,实现图像的旋转(例如,旋转45度)。
  3. 将图像从BGR颜色空间转换为HSV颜色空间,并提取出特定的颜色范围(例如,提取黄色区域)。
  4. 显示处理后的图像,并在图像上标记出识别到的颜色区域。
import cv2
import numpy as np

# 读取图片并调整大小
img = cv2.imread('./color_1.png')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)

# 计算图像旋转的变换矩阵,围绕图像中心旋转45度,缩放因子为1
M = cv2.getRotationMatrix2D((img.shape[1]/2, img.shape[0]/2), 45, 1)

# 应用仿射变换,旋转图像
img_warp = cv2.warpAffine(img,  # 要旋转的图像
                          M,    # 变换矩阵
                          (img.shape[1], img.shape[0]), # 输出图像的大小
                          flags=cv2.INTER_LINEAR,   # 插值方式
                          borderMode=cv2.BORDER_WRAP   # 边缘填充方式,默认是常数填充显示为黑色
                          )

# 将图片从BGR颜色空间转换到HSV颜色空间
img_hsv = cv2.cvtColor(img_warp,cv2.COLOR_BGR2HSV)

# 定义黄色的HSV范围
yellow_min = np.array([26,43,46])
yellow_max = np.array([34,255,255])

# 根据黄色的HSV范围创建掩码
img_color = cv2.inRange(img_hsv,yellow_min,yellow_max)

# 使用中值滤波去除噪声
img_median_blur = cv2.medianBlur(img_color,5)

# 获取椭圆形的结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))

# 腐蚀图像以去除不需要的细节
img_erode = cv2.erode(img_median_blur,kernel)

# 膨胀图像以恢复目标区域的大小
img_erode_dilate = cv2.dilate(img_erode,kernel)

# 查找轮廓
contours,hierarchy = cv2.findContours(img_erode_dilate,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# 复制原图以绘制轮廓
img_warp_copy = img_warp.copy()


# 遍历所有轮廓,筛选出面积符合要求的轮廓并绘制
for i in contours:
    if cv2.contourArea(i)<200 or cv2.contourArea(i)>20000000:
        continue
    cv2.drawContours(img_warp_copy,[i],0,(0,0,255),2)

# 显示原图和绘制了轮廓的图像
cv2.imshow('img',img)
cv2.imshow('img_draw',img_warp_copy)
cv2.waitKey(0)

4、编写程序,读取一张彩色图像,执行以下操作

  1. 找到原图 和目标图的四个点,获取透视变换矩阵
  2. 对图像应用透视变换,实现油画区域的矫正
# 导入OpenCV和NumPy库
import cv2
import numpy as np

# 读取图片文件
img = cv2.imread('./youhua.png')

# 定义四个点,这些点是图片中需要被变换的区域的四个角点
points1 = np.float32([
    [174,143],  # 左上角点
    [623,37],   # 右上角点
    [90,492],   # 左下角点
    [656,550]   # 右下角点
])

# 计算包围points1的最小外接矩形的四个角点
points2 = np.float32([
    [min(points1[:,0]),min(points1[:,1])],  # 左上角点
    [max(points1[:,0]),min(points1[:,1])],  # 右上角点
    [min(points1[:,0]),max(points1[:,1])],  # 左下角点
    [max(points1[:,0]),max(points1[:,1])]   # 右下角点
])

# 使用getPerspectiveTransform函数计算透视变换矩阵M
M = cv2.getPerspectiveTransform(points1, points2)

# 使用warpPerspective函数对图片进行透视变换
dst = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))

# 计算变换后图片的最小外接矩形的坐标
min_x, min_y = points2.min(axis=0).astype(int)
max_x, max_y = points2.max(axis=0).astype(int)

# 根据最小外接矩形的坐标裁剪变换后的图片
cropped_dst = dst[min_y:max_y, min_x:max_x]

# 显示原始图片
cv2.imshow('img', img)

# 显示裁剪后的变换图片
cv2.imshow('cropped_dst', cropped_dst)

# 等待按键,0表示无限等待直到有按键按下
cv2.waitKey(0)

5、请编写一段Python代码,使用OpenCV库对一张图像进行以下处理:

  1. 将图像转换为灰度图。
  2. 使用高斯滤波器平滑图像,内核大小为5x5,标准差为1。
  3. 使用Canny边缘检测算法检测图像边缘,阈值1为50,阈值2为150。
  4. 在检测到的边缘图像上绘制轮廓,轮廓颜色为红色,厚度为2。
import cv2

# 读取图片文件
img = cv2.imread("./picture.png")

# 调整图片大小,便于处理和显示
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)

# 将图片转换为灰度图,便于后续的二值化处理
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 使用Otsu's thresholding方法对灰度图进行二值化处理
ret,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# 对二值化的图片进行高斯模糊处理,减少噪声
img_blur = cv2.GaussianBlur(img_binary,(5,5),1)

# 使用Canny算法对模糊处理后的图片进行边缘检测
img_canny = cv2.Canny(img_blur,50,150)

# 找到边缘检测后的图片中的轮廓
contours, _ = cv2.findContours(img_canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

# 复制原图
img_copy = img.copy()
# 在复制的图片上绘制找到的轮廓
img_draw = cv2.drawContours(img_copy,contours,-1,(0,0,255),2)

# 显示二值化后的图片
cv2.imshow("img_binary",img_binary)
# 显示经过高斯模糊处理后的图片
cv2.imshow("img_blur",img_blur)
# 显示边缘检测后的图片
cv2.imshow("img_canny",img_canny)
# 显示绘制了轮廓的图片
cv2.imshow("img_draw",img_draw)

# 等待用户按键,任意键按下后关闭所有图片窗口
cv2.waitKey(0)

6、你正在开发一个自动驾驶系统,需要识别交通信号灯的颜色(红、黄、绿)。请设计一个简化的流程,说明如何使用OpenCV来识别交通信号灯的颜色。

  1. 读取包含交通信号灯的图像。
  2. 转换图像到HSV颜色空间。
  3. 分别为红、黄、绿三种颜色定义HSV范围,并创建三个掩膜。
  4. 对每个掩膜进行轮廓检测,识别出可能的信号灯区域。
import cv2
import numpy as np

# 加载图像
img = cv2.imread('./demo111.png')

# 转换到 HSV 色彩空间
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 红色范围
red_min1 = np.array([0, 43, 46])
red_max1 = np.array([10, 255, 255])
red_min2 = np.array([156, 43, 46])
red_max2 = np.array([180, 255, 255])

# 黄色范围
yellow_min = np.array([26, 43, 46])
yellow_max = np.array([34, 255, 255])

# 绿色范围
green_min = np.array([35, 43, 46])
green_max = np.array([77, 255, 255])

# 创建各个颜色的掩码
img_mask1 = cv2.inRange(img_hsv, red_min1, red_max1)
img_mask2 = cv2.inRange(img_hsv, red_min2, red_max2)

# 合并红色区域的掩码
img_mask11 = cv2.bitwise_or(img_mask1, img_mask2)

# 黄色区域掩码
img_mask22 = cv2.inRange(img_hsv, yellow_min, yellow_max)

# 绿色区域掩码
img_mask33 = cv2.inRange(img_hsv, green_min, green_max)

# 合并所有颜色区域的掩码
mask_all = cv2.bitwise_or(cv2.bitwise_or(img_mask11, img_mask22), img_mask33)

# 查找轮廓
contours, _ = cv2.findContours(mask_all, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 创建图像副本进行绘制
img_copy = img.copy()

# 绘制每个轮廓的矩形框
for i in contours:
    if cv2.contourArea(i) < 2000:
        continue
    (x, y), radius = cv2.minEnclosingCircle(i)
    (x, y, radius) = np.int32((x, y, radius))
    # 画圆
    cv2.circle(img_copy, (x, y), radius, (255, 0, 255), 3)

# 显示原图、掩码图和绘制矩形后的图像
cv2.imshow('img', img)
cv2.imshow('mask_all', mask_all)
cv2.imshow('img_copy', img_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()

7、在一家生产彩色玩具的工厂中,需要检测产品是否按照正确的颜色进行生产。请设计一个使用OpenCV的自动化检测系统,该系统能够识别并报告不符合颜色标准的产品。

  1. 设定产品的标准颜色范围(HSV值)。
  2. 使用摄像头或图像文件获取待检测产品的图像。
  3. 转换图像到HSV颜色空间。
  4. 为每种标准颜色创建掩膜,并与产品图像进行比对。
  5. 识别出颜色不符合标准的产品,并记录或报告。
import cv2
import numpy as np

# 读取图像并调整大小
image = cv2.imread('./duck.png')  # 读取指定路径的图像
image = cv2.resize(image, (600, 600))  # 将图像调整为600x600像素

# 将BGR图像转换为HSV图像
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)  # OpenCV默认读取图像为BGR格式,转换为HSV格式,便于颜色范围的筛选

# 定义橡皮鸭的标准颜色范围(HSV值)
# 每种颜色都包含了其对应的最小和最大HSV值范围,以及用于绘制矩形的颜色
colors = {
    'red': {'min': np.array([0, 100, 100]), 'max': np.array([10, 255, 255]), 'color': (0, 0, 255)},
    'blue': {'min': np.array([70, 50, 50]), 'max': np.array([130, 255, 255]), 'color': (255, 0, 0)},
    'green': {'min': np.array([50, 100, 100]), 'max': np.array([70, 255, 255]), 'color': (0, 255, 0)},
    'pink': {'min': np.array([140, 50, 50]), 'max': np.array([180, 255, 255]), 'color': (255, 0, 255)},
    'black': {'min': np.array([0, 0, 0]), 'max': np.array([180, 255, 46]), 'color': (0, 0, 0)},
}

# 遍历每种颜色,检测图像中的相应区域
for color_name, color_range in colors.items():
    # 使用inRange函数根据HSV值范围生成掩膜,提取出符合范围的颜色区域
    mask = cv2.inRange(hsv, color_range['min'], color_range['max'])

    # 使用findContours检测掩膜中的轮廓
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 遍历检测到的轮廓
    # 遍历所有轮廓,筛选出面积符合要求的轮廓并绘制
    for cnt in contours:
        if cv2.contourArea(cnt) < 600 or cv2.contourArea(cnt) > 20000000:
            continue
        M = cv2.moments(cnt)
        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])
        cv2.drawContours(image, [cnt], 0, (0, 0, 255), 2)
        cv2.putText(image, 'Unqualified', (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color_range['color'], 2)

# 显示处理后的图像,包含标记出的颜色区域
cv2.imshow('image', image)
cv2.waitKey(0)  # 等待按键输入后关闭图像窗口

8、图像预处理与特征提取‌

  1. 将图像转换为灰度图
  2. 对灰度图进行二值化处理
  3. 使用形态学变换去除噪声【开运算】
  4. 检测图像中的边缘
  5. 查找并绘制图像中的轮廓
  6. 逐一遍历轮廓,输出所有四边形的周长 和 面积。
import cv2
import numpy as np

# 读取图像
img = cv2.imread('./03.png')
# 调整图像大小
img = cv2.resize(img, (0, 0), fx=1.5, fy=1.5)
# 创建图像副本,用于后续绘制轮廓和标签
img_copy = img.copy()

# 使用高斯模糊处理图像,减少噪声
img_blur = cv2.GaussianBlur(img, (3, 3), 1)

# 将模糊图像转换为灰度图像
img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)

# 使用Otsu's thresholding方法进行二值化处理,得到二值图像
_, img_binary = cv2.threshold(img_gray, 175, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 查找二值图像中的轮廓
contours, h = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍历所有轮廓
for cnt in contours:
    # 计算轮廓的矩
    M = cv2.moments(cnt)
    # 如果轮廓的面积为0,则跳过
    if int(M['m00']) == 0:
        continue
    # 计算轮廓的周长
    arc_len = cv2.arcLength(cnt, True)
    # 计算轮廓的面积
    area = cv2.contourArea(cnt)
    # 近似轮廓
    approx = cv2.approxPolyDP(cnt, float(0.04) * arc_len, True)

    # 计算轮廓的中心
    cX = int(M['m10'] / M['m00'])
    cY = int(M['m01'] / M['m00'])

    # 根据近似轮廓的点数判断形状
    if len(approx) == 4:
       # 在轮廓中显示周长和面积
        cv2.putText(img_copy, 'Perimeter: ' + str(round(arc_len, 2)) + ' Area: ' + str(round(area, 2)), (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1)

    # 绘制轮廓
    cv2.drawContours(img_copy, [cnt], -1, (0, 255, 0), 2)

# 显示绘制了轮廓和标签的图像
cv2.imshow('img_copy', img_copy)
# 等待按键按下
cv2.waitKey(0)

9、假设你正在开发一个车牌识别系统,首先需要从图像中识别出车牌区域。请描述并编写代码实现以下步骤:

  1. 读取一张包含车牌的图像。
  2. 将图像转换为灰度图以简化处理。
  3. 使用高斯滤波器平滑图像,减少噪声干扰。
  4. 应用Canny边缘检测算法检测图像中的边缘。
  5. 查找图像中的轮廓。
  6. 逐一遍历轮廓。
  7. 设定一个面积双阈值,只保留面积在该阈值的轮廓。
  8. 计算这些轮廓的长宽比,长宽比ratio在2到5.5之间的,在原图上用矩形框标出,这些轮廓可能是车牌的候选区域。
import cv2

# 读取图片文件
img= cv2.imread('./OIP-C.jpg')

# 对图片进行缩放,这里缩小到原图的一半
img = cv2.resize(img,(0,0),fx=0.7,fy=0.7)

# 复制原图
img_copy = img.copy()

# 将图片转换为灰度图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 使用高斯滤波器进行平滑处理
img_gray = cv2.GaussianBlur(img_gray,(5,5),0)

# 应用Canny边缘检测算法检测图像中的边缘。
img_canny = cv2.Canny(img_gray,50,150)

# 找到轮廓
contours, hierarchy = cv2.findContours(img_canny,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# 遍历所有轮廓
for i in contours:
    # 筛选轮廓面积在10000到15000之间的轮廓
    if 10000 < cv2.contourArea(i) < 15000:
        x,y,w,h = cv2.boundingRect(i)
        ratio = float(w)/h
        # 筛选长宽比在2到5.5之间的矩形
        if 2 < ratio < 5.5:
            # 画矩形
            cv2.rectangle(img_copy,cv2.boundingRect(i),(0,255,0))

# 显示原图
cv2.imshow('img',img)
# 显示绘制了轮廓的图片
cv2.imshow('img_draw',img_copy)
# 等待按键按下
cv2.waitKey(0)


网站公告

今日签到

点亮在社区的每一天
去签到