一、编程题
读取一张彩色图像并将其转换为灰度图。
import cv2
# 读取彩色图像
image_path = 'path_to_your_image.jpg' # 替换为你的图像路径
color_image = cv2.imread(image_path)
# 检查图像是否成功加载
if color_image is None:
print("图像加载失败,请检查图像路径")
else:
# 将彩色图像转换为灰度图
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
# 显示彩色图像和灰度图
cv2.imshow('Color Image', color_image)
cv2.imshow('Gray Image', gray_image)
# 等待按键按下然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存灰度图像(可选)
gray_image_path = 'gray_image.jpg' # 替换为你想保存的灰度图像路径
cv2.imwrite(gray_image_path, gray_image)
print(f"灰度图像已保存至 {gray_image_path}")
二、编程题
题目1:二值化与形态学操作
编写程序,读取一张彩色图像【flower.png】,将其转换为灰度图,然后进行二值化处理。
接着,对二值化后的图像执行腐蚀和膨胀操作,并显示处理前后的图像。
import cv2
import numpy as np
# 读取彩色图像
image_path = 'flower.png'
color_image = cv2.imread(image_path)
# 转换为灰度图
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
# 二值化处理
_, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)
# 定义核(结构元素)
kernel = np.ones((3, 3), np.uint8)
# 腐蚀操作
eroded_image = cv2.erode(binary_image, kernel, iterations=1)
# 膨胀操作
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
# 显示处理前后的图像
cv2.imshow('Original Image', color_image)
cv2.imshow('Binary Image', binary_image)
cv2.imshow('Eroded Image', eroded_image)
cv2.imshow('Dilated Image', dilated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
题目2:图像变换与颜色识别
编写程序,读取一张彩色图像,执行以下操作:
- 将图像缩放至指定大小(例如,宽度和高度都缩小为原来的一半)。
- 对缩放后的图像应用仿射变换,实现图像的旋转(例如,旋转45度)。
- 将图像从BGR颜色空间转换为HSV颜色空间,并提取出特定的颜色范围(例如,提取黄色区域)。
- 显示处理后的图像,并在图像上标记出识别到的颜色区域。
import cv2
import numpy as np
# 读取彩色图像
image_path = 'your_image.jpg' # 替换为你的图像路径
color_image = cv2.imread(image_path)
# 1. 缩放图像
scaled_image = cv2.resize(color_image, (0, 0), fx=0.5, fy=0.5)
# 2. 仿射变换(旋转45度)
rows, cols, _ = scaled_image.shape
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
rotated_image = cv2.warpAffine(scaled_image, M, (cols, rows))
# 3. 转换为HSV颜色空间
hsv_image = cv2.cvtColor(rotated_image, cv2.COLOR_BGR2HSV)
# 定义黄色的HSV范围
lower_yellow = np.array([20, 100, 100], dtype=np.uint8)
upper_yellow = np.array([30, 255, 255], dtype=np.uint8)
# 4. 提取黄色区域
mask = cv2.inRange(hsv_image, lower_yellow, upper_yellow)
result = cv2.bitwise_and(rotated_image, rotated_image, mask=mask)
# 显示处理后的图像
cv2.imshow('Original Image', color_image)
cv2.imshow('Rotated Image', rotated_image)
cv2.imshow('Yellow Mask', mask)
cv2.imshow('Extracted Yellow', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
题目3:图像矫正
编写程序,读取一张彩色图像,执行以下操作
- 找到原图 和目标图的四个点,获取透视变换矩阵
- 对图像应用透视变换,实现油画区域的矫正
import cv2 import numpy as np # 读取彩色图像 image_path = 'your_image_with_painting.jpg' # 替换为你的图像路径 color_image = cv2.imread(image_path) # 定义原图和目标图的四个点 # 这些点需要根据你的实际图像进行手动选择 src_points = np.float32([[100, 100], [200, 100], [100, 200], [200, 200]]) dst_points = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]]) # 1. 获取透视变换矩阵 M = cv2.getPerspectiveTransform(src_points, dst_points) # 2. 应用透视变换 height, width = dst_points[2][1], dst_points[1][0] warped_image = cv2.warpPerspective(color_image, M, (width, height)) # 显示处理后的图像 cv2.imshow('Original Image', color_image) cv2.imshow('Warped Image', warped_image) cv2.waitKey(0) cv2.destroyAllWindows()
四、编程题(共10分)
请编写一段Python代码,使用OpenCV库对一张图像进行以下处理:
- 将图像转换为灰度图。
- 使用高斯滤波器平滑图像,内核大小为5x5,标准差为1。
- 使用Canny边缘检测算法检测图像边缘,阈值1为50,阈值2为150。
- 在检测到的边缘图像上绘制轮廓,轮廓颜色为红色,厚度为2。
import cv2 import numpy as np # 读取图像 image_path = 'your_image.jpg' # 替换为你的图像路径 image = cv2.imread(image_path) # 1. 将图像转换为灰度图 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 2. 使用高斯滤波器平滑图像,内核大小为5x5,标准差为1 blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 1) # 3. 使用Canny边缘检测算法检测图像边缘,阈值1为50,阈值2为150 edges = cv2.Canny(blurred_image, 50, 150) # 4. 在检测到的边缘图像上绘制轮廓,轮廓颜色为红色,厚度为2 # 为了在原始图像上绘制轮廓,我们需要先找到边缘的轮廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建一个用于绘制轮廓的图像副本 image_with_contours = image.copy() # 绘制轮廓 cv2.drawContours(image_with_contours, contours, -1, (0, 0, 255), 2) # 显示处理后的图像 cv2.imshow('Original Image', image) cv2.imshow('Gray Image', gray_image) cv2.imshow('Blurred Image', blurred_image) cv2.imshow('Edges Detected', edges) cv2.imshow('Image with Contours', image_with_contours) # 等待按键并关闭所有窗口 cv2.waitKey(0) cv2.destroyAllWindows()
交通信号灯识别:
你正在开发一个自动驾驶系统,需要识别交通信号灯的颜色(红、黄、绿)。请设计一个简化的流程,说明如何使用OpenCV来识别交通信号灯的颜色。
思路分析:
- 读取包含交通信号灯的图像。
- 转换图像到HSV颜色空间。
- 分别为红、黄、绿三种颜色定义HSV范围,并创建三个掩膜。
- 对每个掩膜进行轮廓检测,识别出可能的信号灯区域。
import cv2 # 读取图像 image = cv2.imread('demo111.png') # 转换图像到HSV颜色空间 hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 定义HSV范围 red_lower = (0, 100, 100) red_upper = (10, 255, 255) yellow_lower = (15, 100, 100) yellow_upper = (30, 255, 255) green_lower = (40, 40, 40) green_upper = (90, 255, 255) # 创建掩膜 mask_red = cv2.inRange(hsv, red_lower, red_upper) mask_yellow = cv2.inRange(hsv, yellow_lower, yellow_upper) mask_green = cv2.inRange(hsv, green_lower, green_upper) # 轮廓检测函数 def detect_contours(mask, color): contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: if cv2.contourArea(contour) > 100: x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(image, (x, y), (x+w, y+h), color, 2) # 对每个掩膜进行轮廓检测 detect_contours(mask_red, (0, 0, 255)) # 红色用红色框 detect_contours(mask_yellow, (0, 255, 255)) # 黄色用黄色框 detect_contours(mask_green, (0, 255, 0)) # 绿色用绿色框 # 显示结果 cv2.imshow('Detected Traffic Lights', image) cv2.waitKey(0) cv2.destroyAllWindows()
产品质量检测:
在一家生产彩色玩具的工厂中,需要检测产品是否按照正确的颜色进行生产。请设计一个使用OpenCV的自动化检测系统,该系统能够识别并报告不符合颜色标准的产品。
思路分析:
- 设定产品的标准颜色范围(HSV值)。
- 使用摄像头或图像文件获取待检测产品的图像。
- 转换图像到HSV颜色空间。
- 为每种标准颜色创建掩膜,并与产品图像进行比对。
- 识别出颜色不符合标准的产品,并记录或报告。
-
import cv2 import numpy as np # 设定黄色HSV范围 yellow_lower = (15, 100, 100) yellow_upper = (30, 255, 255) # 读取待检测产品的图像 image = cv2.imread('duck.png') # 转换图像到HSV颜色空间 hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 创建黄色掩膜 mask_yellow = cv2.inRange(hsv, yellow_lower, yellow_upper) # 使用轮廓检测找到掩膜中的所有轮廓 contours, _ = cv2.findContours(mask_yellow, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 设定面积阈值 min_area = 500 # 根据实际情况调整 # 遍历所有轮廓,剔除面积过小的轮廓 filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) >= min_area] # 检查是否有符合面积要求的黄色区域 if filtered_contours: print("Detected yellow duck toy with sufficient area.") else: print("No yellow duck toy detected or yellow area is too small.") # 可选:绘制轮廓和显示结果 cv2.drawContours(image, filtered_contours, -1, (0, 255, 0), 3) cv2.imshow('Original Image with Contours', image) cv2.imshow('Yellow Mask', mask_yellow) cv2.waitKey(0) cv2.destroyAllWindows()
图像预处理与特征提取
- 将图像转换为灰度图
- 对灰度图进行二值化处理
- 使用形态学变换去除噪声【开运算】
- 检测图像中的边缘
- 查找并绘制图像中的轮廓
- 逐一遍历轮廓,输出所有四边形的周长 和 面积。
import cv2 import numpy as np # 读取图像 image = cv2.imread('path_to_your_image.jpg') # 1. 将图像转换为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 2. 对灰度图进行二值化处理 _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 3. 使用形态学变换去除噪声【开运算】 kernel = np.ones((5, 5), np.uint8) opened = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel) # 4. 检测图像中的边缘 edges = cv2.Canny(opened, 50, 150) # 5. 查找并绘制图像中的轮廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 创建一个用于绘制轮廓的图像副本 image_contours = image.copy() cv2.drawContours(image_contours, contours, -1, (0, 255, 0), 2) # 6. 逐一遍历轮廓,输出所有四边形的周长和面积 for contour in contours: # 计算轮廓的周长 perimeter = cv2.arcLength(contour, True) # 使用多边形逼近来获取近似的四边形轮廓 approx = cv2.approxPolyDP(contour, 0.02 * perimeter, True) # 仅处理四边形 if len(approx) == 4: # 计算面积 area = cv2.contourArea(approx) print(f'四边形周长: {perimeter:.2f}, 面积: {area:.2f}') # 绘制四边形轮廓 cv2.drawContours(image_contours, [approx], -1, (255, 0, 0), 2) # 显示处理结果 cv2.imshow('Gray Image', gray) cv2.imshow('Binary Image', binary) cv2.imshow('Opened Image', opened) cv2.imshow('Edges Image', edges) cv2.imshow('Contours Image', image_contours) # 等待按键按下后关闭所有窗口 cv2.waitKey(0) cv2.destroyAllWindows()
车牌识别预处理
假设你正在开发一个车牌识别系统,首先需要从图像中识别出车牌区域。请描述并编写代码实现以下步骤:
- 读取一张包含车牌的图像。
- 将图像转换为灰度图以简化处理。
- 使用高斯滤波器平滑图像,减少噪声干扰。
- 应用Canny边缘检测算法检测图像中的边缘。
- 查找图像中的轮廓。
- 逐一遍历轮廓。
- 设定一个面积双阈值,只保留面积在该阈值的轮廓。
- 计算这些轮廓的长宽比,长宽比ratio在2到5.5之间的,在原图上用矩形框标出,这些轮廓可能是车牌的候选区域。
import cv2 import numpy as np # 1. 读取包含车牌的图像 image_path = 'path_to_your_car_image.jpg' # 请替换为你的图像文件路径 image = cv2.imread(image_path) # 2. 将图像转换为灰度图 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 3. 使用高斯滤波器平滑图像 blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0) # 4. 应用Canny边缘检测算法 edges = cv2.Canny(blurred_image, 50, 150) # 5. 查找图像中的轮廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 设定面积双阈值 min_area = 1000 # 最小面积阈值,根据实际情况调整 max_area = 15000 # 最大面积阈值,根据实际情况调整 # 6. 逐一遍历轮廓 for contour in contours: # 7. 只保留面积在阈值范围内的轮廓 area = cv2.contourArea(contour) if min_area < area < max_area: # 获取轮廓的外接矩形 x, y, w, h = cv2.boundingRect(contour) # 8. 计算长宽比,并筛选出可能的车牌候选区域 ratio = w / h if 2 < ratio < 5.5: # 在原图上绘制矩形框 cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) # 显示处理后的图像 cv2.imshow('Car Image with Possible License Plate Regions', image) # 等待按键并关闭窗口 cv2.waitKey(0) cv2.destroyAllWindows()