opencv-python的简单练习

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

import cv2

img = cv2.imread("../../12.11/flower.png")

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.imshow("img", img)
cv2.imshow("img_gray", img_gray)
cv2.waitKey(0)

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

import cv2  # 导入OpenCV库,用于图像处理和计算机视觉任务

# 使用cv2.imread函数读取指定路径下的图像文件
img = cv2.imread("../../12.11/flower.png")

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

# 对灰度图像应用阈值操作,将其转换为二值图像
# 参数解释:
# img_gray:输入图像(灰度图)
# 127:阈值,像素值大于此值的将被设置为最大值(255),小于此值的将被设置为0
# 255:最大值,用于设置超过阈值的像素值
# cv2.THRESH_BINARY:阈值类型,表示二值化
# ret:返回的阈值(在此例中未使用)
# img_thresh:阈值化后的图像
ret, img_thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

# 创建一个椭圆形的结构元素,用于后续的腐蚀和膨胀操作
# 参数解释:
# cv2.MORPH_ELLIPSE:表示椭圆形结构元素
# (9, 9):结构元素的大小
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))

# 对二值图像应用腐蚀操作
# 腐蚀操作会使图像中的白色区域变小,黑色区域变大,通常用于去除小的噪声点或连接物体之间的细小间隙
img_erode = cv2.erode(img_thresh, kernel)

# 对腐蚀后的图像应用膨胀操作
# 膨胀操作会使图像中的白色区域变大,黑色区域变小,通常用于填充物体内部的细小空洞或连接相邻的物体
img_dilate = cv2.dilate(img_erode, kernel)

# 显示原始图像、腐蚀后的图像和膨胀后的图像
cv2.imshow("img", img)
cv2.imshow("img_erode", img_erode)
cv2.imshow("img_dilate", img_dilate)

# 等待用户按键,按键后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()  # 添加此行以确保所有窗口在按键后被关闭

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

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

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

# 调整图像大小
img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

# 获取图像中心并计算旋转矩阵
center = (img.shape[1] / 2, img.shape[0] / 2)
M = cv2.getRotationMatrix2D(center, 45, 0.5)

# 应用仿射变换
img = cv2.warpAffine(img, M, (img.shape[0], img.shape[1]), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_WRAP)

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

# 定义黄色范围
lower_yellow = np.array([26, 43, 46])
upper_yellow = np.array([34, 255, 255])

# 创建黄色掩膜
mask = cv2.inRange(img_hsv, lower_yellow, upper_yellow)

# 应用掩膜到原图像
img = cv2.bitwise_and(img, img, mask=mask)

# 找到黄色区域的轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍历每个轮廓,并在其上绘制文本
for contour in contours:
    # 找到轮廓的边界框
    x, y, w, h = cv2.boundingRect(contour)
    # 在边界框的左上角绘制文本
    cv2.putText(img, "yellow", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2, cv2.LINE_AA)

# 显示结果图像
cv2.imshow("color", img)
cv2.waitKey(0)
cv2.destroyAllWindows()  # 释放所有窗口

 

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

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

# 读取图像
img = cv2.imread('../../12.12/youhua.png')
# 高斯滤波
img_blur = cv2.GaussianBlur(img, (3, 3), 1)

# 灰度化
img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)

# 二值化
_, img_binary = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 寻找轮廓
contours, _ = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]
img_copy = img.copy()

img_copy = cv2.drawContours(img_copy, [cnt], -1, (0, 0, 255), 2)

# 找到card的轮廓  做多边形逼近  获取四个顶点
arc_len = cv2.arcLength(cnt, True)
app_rox = cv2.approxPolyDP(cnt, float(0.04) * arc_len, True)
img_draw = img.copy()


points1 = np.float32(app_rox).reshape(-1, 2)

points2 = np.float32([
    [max(points1[:, 0]), min(points1[:, 1])],  # 右上角
    [min(points1[:, 0]), min(points1[:, 1])],  # 左上角
    [min(points1[:, 0]), max(points1[:, 1])],  # 左下角
    [max(points1[:, 0]), max(points1[:, 1])],  # 右下角
]
)

M = cv2.getPerspectiveTransform(points1, points2)
img_draw = cv2.warpPerspective(img_draw, M, (img.shape[1], img.shape[0]))



# 输出图形
cv2.imshow('img', img)
cv2.imshow('img_copy', img_copy)
cv2.imshow('img_draw', img_draw)
cv2.waitKey(0)

 

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

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

 


import cv2


img = cv2.imread("../../12.11/color.png")

# 调整图像大小,fx和fy分别为宽度和高度的缩放比例,这里都设置为0.5,表示图像大小减半
img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

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

# 对灰度图像应用高斯模糊,以减少噪声和细节层次,这里使用的核大小为5x5,标准差为1
img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)

# 使用Canny边缘检测算法检测图像中的边缘,这里设置的阈值分别为50和150
img_canny = cv2.Canny(img_blur, 50, 150)

# 查找图像中的轮廓,cv2.RETR_EXTERNAL表示只检索最外层轮廓,cv2.CHAIN_APPROX_NONE表示保存轮廓上所有点
contours, hierarchy = cv2.findContours(img_canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)


cv2.drawContours(img, contours, -1, (0, 0, 255), 2)
cv2.imshow("img", img)
cv2.waitKey(0)

六、你正在开发一个自动驾驶系统,需要识别交通信号灯的颜色(红、黄、绿)。请设计一个简化的流程,说明如何使用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)

# 定义颜色范围(HSV空间)
# 红色的两个范围
lower_red1 = np.array([0, 120, 70])
upper_red1 = np.array([10, 255, 255])

lower_red2 = np.array([156, 43, 46])
upper_red2 = np.array([180, 255, 255])

# 绿色范围
lower_green = np.array([25, 43, 46])
upper_green = np.array([77, 255, 255])

# 黄色范围
lower_yellow = np.array([11, 43, 46])
upper_yellow = np.array([25, 255, 255])

# 创建掩膜
mask_red1 = cv2.inRange(img_hsv, lower_red1, upper_red1)
mask_red2 = cv2.inRange(img_hsv, lower_red2, upper_red2)
mask_red = cv2.bitwise_or(mask_red1, mask_red2)

mask_green = cv2.inRange(img_hsv, lower_green, upper_green)
mask_yellow = cv2.inRange(img_hsv, lower_yellow, upper_yellow)

# 合并掩膜
mask_all = cv2.bitwise_or(mask_red, mask_green)
mask_all = cv2.bitwise_or(mask_all, mask_yellow)

# 对每个颜色进行轮廓检测
def detect_color(mask, color_name):
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > 500:  # 过滤掉小面积的噪声
            # 计算外接矩形
            x, y, w, h = cv2.boundingRect(contour)
            # 绘制轮廓和矩形
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
            # 在信号灯区域内标记颜色
            cv2.putText(img, color_name, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

# 识别红色、绿色和黄色
detect_color(mask_red, "Red")
detect_color(mask_green, "Green")
detect_color(mask_yellow, "Yellow")

# 显示结果
cv2.imshow("Traffic Lights Detection", img)
cv2.waitKey(0)

 

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

‌思路分析‌:

  1. 设定产品的标准颜色范围(HSV值)。
  2. 使用摄像头或图像文件获取待检测产品的图像。
  3. 转换图像到HSV颜色空间。
  4. 为每种标准颜色创建掩膜,并与产品图像进行比对。
  5. 识别出颜色不符合标准的产品,并记录或报告。
# 在一家生产彩色玩具的工厂中,需要检测产品是否按照正确的颜色进行生产。请设计一个使用OpenCV的自动化检测系统,该系统能够识别并报告不符合颜色标准的产品。
# ‌思路分析‌:
# 1.设定产品的标准颜色范围(HSV值)。
# 2.使用摄像头或图像文件获取待检测产品的图像。
# 3.转换图像到HSV颜色空间。
# 4.为每种标准颜色创建掩膜,并与产品图像进行比对。
# 5.识别出颜色不符合标准的产品,并记录或报告。
import cv2
import numpy as np

# 设定标准颜色范围(HSV值)
# 例如红色、黄色、蓝色的HSV范围
color_ranges = {
    'red': {'lower': np.array([0, 120, 70]), 'upper': np.array([10, 255, 255])},
    'green': {'lower': np.array([35, 100, 100]), 'upper': np.array([85, 255, 255])},
    'blue': {'lower': np.array([100, 150, 50]), 'upper': np.array([140, 255, 255])},
    'yellow': {'lower': np.array([20, 100, 100]), 'upper': np.array([30, 255, 255])},
    'black': {'lower': np.array([0, 0, 0]), 'upper': np.array([180, 255, 46])},
    'pink': {'lower': np.array([160, 100, 100]), 'upper': np.array([180, 255, 255])}
}
img = cv2.imread("duck.png")

img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

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

# 为每种标准颜色创建掩膜,并与产品图像进行比对
for color_name, color_range in color_ranges.items():
    mask = cv2.inRange(img_hsv, color_range['lower'], color_range['upper'])
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > 500:
            # 计算外接矩形
            x, y, w, h = cv2.boundingRect(contour)
            # 绘制轮廓和矩形
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
            # 在信号灯区域内标记颜色
            cv2.putText(img, color_name, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)



# 显示结果
cv2.imshow("Product Color Detection", img)
cv2.waitKey(0)

 

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

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

 

import cv2

img = cv2.imread("02.png")
img_copy = img.copy()

img_blur = cv2.GaussianBlur(img, (5, 5), 0)  # 高斯模糊

img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)  # 灰度化

ret,img_thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)  # 二值化

contours, hierarchy = cv2.findContours(img_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 轮廓检测

for c in contours:
    M = cv2.moments(c)  # 计算轮廓的矩
    if M["m00"] == 0:
        continue
    arc_len = cv2.arcLength(c, True)  # 计算轮廓的周长
    app_rox=cv2.approxPolyDP(c, 0.04 * arc_len, True)  # 用指定精度逼近多边形曲线,返回值是逼近的多边形轮廓的点集

    if len(app_rox)==3:
        shape = "triangle"
        color = (0, 0, 255)
    elif len(app_rox)==4:
        x, y, w, h = cv2.boundingRect(app_rox)  # 计算轮廓的外接矩形
        ratio = float(w) / h  # 计算长宽比
        if 0.95 <= ratio <= 1.05:
            shape = "square"
            color = (0, 255, 0)
            print(f"正方形的面积为: {2 * (w + h):.2f}, Area: {w * h:.2f}")
        else:
            shape = "rectangle"
            color = (0, 255, 0)
            print(f"矩形的面积为: {2 * (w + h):.2f}, Area: {w * h:.2f}")
    elif len(app_rox) == 5:
        shape = "pentagon"
        color = (255, 0, 0)
    else:
        shape = "circle"
        color = (0, 255, 255)

    cv2.drawContours(img_copy, [c], -1, (0, 0, 255), 2)  # 画轮廓
    #先激素按轮廓形状的中心坐标
    cX=int(M["m10"] / M["m00"])
    cY=int(M["m01"] / M["m00"])
    # 给不同的形状添加不同的文字颜色:例如:三角形文字颜色为红色,四边形文字颜色为绿色,五边形文字颜色为蓝色,其他形状文字颜色为黄色。
    cv2.putText(img_copy, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)


# cv2.drawContours(img, contours, -1, (0, 0, 255), 2)  # 画轮廓

cv2.imshow("img", img)
cv2.imshow("img_copy", img_copy)
cv2.waitKey(0)



上一篇:外观模式与中介模式的区别


下一篇:写给Pythoner的前端进阶指南(一):前言-深入学习前端后会有哪些新的机遇