5-python图像处理opencv(1.读图,显示,转换,存储)

本文介绍如何使用Python结合OpenCV库进行图像处理的基本操作,包括读取、显示、色彩转换及保存图片。通过实例演示了从加载图片到色彩空间转换的具体步骤,并提供了完整的代码示例。

通过opencv的python接口来,调用opencv函数实现,对图片的载入,显示,颜色转换和保存等

python+opencv的配置

由于:opencv中使用到了python的许多第三方插件,例如 numpy等,以上链接均提供相应配置


一.读图
opencv提供了一个很简单的读图方法, cv2.imread(path)

img = cv2.imread("test1.jpg")

二.显示
opencv 中显示图片需要两步
1.创建一个窗口

cv2.namedWindow("myImage")

2.将图片显示到窗口上

cv2.imshow("myImage",img)

为了防止一闪而过

cv2.waitKey(0) #暂停一下

关闭所有窗口

cv2.destroyAllWindows()

三.色彩变换
opencv中提供了方法 cvtColor(img,cv2.COLOR_RGB2HSV) 创建图像副本,同时也可以对图片进行色彩变换

emptyImage3 = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

有个小的规律,cv.COLOR 后面的东西都有个 2 (two) –> to 即:从什么转化成什么具体转换如下图:(图借鉴的)
这里写图片描述


四.存储
存储,可以使用opencv中的 imwrite(path,img,[int(cv2.IMWRITE_JPEG_QUALITY), 100])
第三个是可选参数不填则默认按照原格式保存

cv2.imwrite("C:/test/save.jpg", img,[int(cv2.IMWRITE_JPEG_QUALITY), 100])

特定格式保存的参数编码:
JPEG:params表示0到100的图片质量(CV_IMWRITE_JPEG_QUALITY),默认值为95;
PNG:params表示压缩级别(CV_IMWRITE_PNG_COMPRESSION),从0到9,其值越大,压缩尺寸越小,压缩时间越长;
PPM / PGM / PBM:params表示二进制格式标志(CV_IMWRITE_PXM_BINARY),取值为0或1,默认值是1。


测试案例

#coding=utf-8
#
# 使用opencv做一个小案例,实现
# 对图片的读取,显示,
# 图片色彩转化 从RGB转换为HSV
# 存储

import cv2

#读图 中文路精可能有问题
img = cv2.imread('C:/test/opencvTest/demoCV1/test.jpg')

# 创建窗口
cv2.namedWindow('imgTest1')

# 显示
cv2.imshow('imgTest1',img)

# 色彩转换
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# 创建窗口
cv2.namedWindow('imgTest2')
# 显示
cv2.imshow('imgTest2',img2)
#暂停
cv2.waitKey(0)
#关闭所有窗口
cv2.destroyAllWindows()
#存储位jpg格式,,缩小比率为 0.8
cv2.imwrite("C:/test/opencvTest/demoCV1/save.jpg", img2,[int(cv2.IMWRITE_JPEG_QUALITY), 80])

测试结果:
这里写图片描述
这里写图片描述

参考文章:
http://blog.youkuaiyun.com/sunny2038/article/details/9057415

import cv2 # 计算机视觉库 import numpy as np# 数组与矩阵运算 import matplotlib.pyplot as plt# 画图查看结果 # ------------------ 图片路径 ------------------ IMG_PATH = 'road.jpg' # 原图路径 # ------------------------------------------------------ def main(): # 1. 读图 bgr = cv2.imread(IMG_PATH) # OpenCV 默认以 BGR 顺序读入 if bgr is None: # 路径错误/文件损坏时给出提示 raise FileNotFoundError(IMG_PATH) rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)# 转 RGB,方便 matplotlib 显示 hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV) # 转 HSV,便于颜色过滤 # 2. 白色标线颜色过滤(饱和度极低 + 亮度高) # HSV 中 H=色相,S=饱和度,V=亮度;白色 S 很小,V 很大 lower_white = np.array([0, 0, 180])# 下界:H 任意,S<25,V>180 upper_white = np.array([180, 25, 255]) white_mask = cv2.inRange(hsv, lower_white, upper_white)# 二值图,白色区域 255,其余 0 # 3. 形态学 opening 去掉路面亮斑噪点 # opening = 先腐蚀再膨胀,可消除小颗粒亮斑,保留细长标线 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 3×3 矩形核 white_mask = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, kernel, iterations=1) # 4. 边缘检测 # Canny 边缘:只保留白色区域的边缘像素,方便后续霍夫找直线 edges = cv2.Canny(white_mask, 50, 150) # 5. 概率霍夫直线检测 # 参数含义:rho=1 像素,theta=1 度,累加器阈值 10,最短 10 像素,最大断隙 5 像素 linesP = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=10, minLineLength=10, maxLineGap=5) # 6. 简单几何过滤:去掉太“胖”的线段(路面大块边缘) # 车道线通常细长;路面边缘往往又短又“宽” def filter_lines(lines, max_side=25): if lines is None: return [] good = [] for l in lines: x1, y1, x2, y2 = l[0] if max(abs(x2-x1), abs(y2-y1)) < max_side: continue good.append(l) return good good_lines = filter_lines(linesP) # 7. 画线,把过滤后的线段画到空白图上 line_img = np.zeros_like(rgb) for l in good_lines: x1, y1, x2, y2 = l[0] # 如果横、纵距离都小于 max_side,则认为太“胖”,丢弃 cv2.line(line_img, (x1, y1), (x2, y2), (0, 255, 0), thickness=2)# 绿色,2 像素宽 # 8. 叠加:原图 80% 透明度 + 线图 100% 透明度 blend = cv2.addWeighted(rgb, 0.8, line_img, 1.0, 0) # 9. 可视化:三栏对比 plt.figure(figsize=(15, 5)) plt.subplot(131) plt.imshow(rgb) plt.title('Original') plt.axis('off') plt.subplot(132) plt.imshow(white_mask, cmap='gray') plt.title('White mask') plt.axis('off') plt.subplot(133) plt.imshow(blend) plt.title('Only white lane lines') plt.axis('off') plt.tight_layout() plt.show() # 当脚本被直接运行时执行 main() if __name__ == '__main__': main()
最新发布
10-19
### 代码原理分析 #### 1. 读取视频帧 ```python def read_frames(video_path): cap = cv2.VideoCapture(video_path) frames = [] while cap.isOpened(): ret, frame = cap.read() if ret: frames.append(frame) else: break cap.release() return frames ``` 该函数使用`cv2.VideoCapture`打开视频文件,逐帧读取视频内容,将每一帧图像存储在列表`frames`中,最后释放视频捕获对象。 #### 2. 创建掩码并应用到图片上 ```python def apply_mask(frame): height, width = frame.shape[:2] mask = np.zeros_like(frame) roi_vertices = [ (0, height), (width / 2 - 50, height / 2 + 50), (width / 2 + 50, height / 2 + 50), (width, height) ] roi_vertices = np.array([roi_vertices], np.int32) cv2.fillPoly(mask, roi_vertices, (255, 255, 255)) masked_frame = cv2.bitwise_and(frame, mask) return masked_frame ``` 此函数首先创建一个与输入帧大小相同的全零掩码,然后定义一个感兴趣区域(ROI),使用`cv2.fillPoly`将该区域填充为白色,最后通过按位与操作将掩码应用到输入帧上,只保留感兴趣区域的内容。 #### 3. 图像阈值化 ```python def thresholding(frame): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) return thresh ``` 该函数将输入帧转换为灰度图像,然后使用`cv2.threshold`进行二值化处理,将灰度值大于 127 的像素设为 255,小于等于 127 的像素设为 0。 #### 4. 用霍夫线变换检测车道 ```python def hough_lines(frame): rho = 1 theta = np.pi/180 threshold = 15 min_length = 40 max_gap = 20 lines = cv2.HoughLinesP(frame, rho, theta, threshold, np.array([]), min_length, max_gap) return lines ``` 此函数使用`cv2.HoughLinesP`进行概率霍夫线变换,检测图像中的直线。通过设置参数`rho`、`theta`、`threshold`、`min_length`和`max_gap`来控制检测结果。 #### 5. 将车道画到每张图片上 ```python def draw_lines(frame, lines): line_color = [0, 255, 255] line_width = 4 lefts = [] rights = [] if lines is not None: for line in lines: for x1, y1, x2, y2 in line: k = (y2 - y1) / (x2 - x1) if k < 0: lefts.append(line) else: rights.append(line) for left in lefts: for x1, y1, x2, y2 in left: cv2.line(frame, (x1, y1), (x2, y2), line_color, line_width) for right in rights: for x1, y1, x2, y2 in right: cv2.line(frame, (x1, y1), (x2, y2), line_color, line_width) return frame ``` 该函数根据直线的斜率将检测到的直线分为左右车道线,然后使用`cv2.line`将左右车道线画到输入帧上。 #### 6. 将所有图片合并为视频 ```python def frames_to_video(frames, output_path, fps=20): height, width = frames[0].shape[:2] fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) for frame in frames: out.write(frame) out.release() ``` 此函数使用`cv2.VideoWriter`将处理后的帧列表合并为一个视频文件。 #### 7. 主函数 ```python def lane_detection(video_path, output_path): frames = read_frames(video_path) processed_frames = [] for frame in frames: masked_frame = apply_mask(frame) thresh_frame = thresholding(masked_frame) lines = hough_lines(thresh_frame) frame_with_lines = draw_lines(frame.copy(), lines) processed_frames.append(frame_with_lines) frames_to_video(processed_frames, output_path) ``` 主函数依次调用上述各个函数,完成视频帧的读取、处理和合并,最终生成包含车道线检测结果的视频文件。 ### 代码优化建议 #### 1. 透视变换 在进行霍夫线变换之前,可以使用透视变换将图像转换为鸟瞰图,使车道线在图像中更加平行,便于检测和处理。示例代码如下: ```python def perspective_transform(frame): height, width = frame.shape[:2] src = np.float32([[width / 2 - 50, height / 2 + 50], [width / 2 + 50, height / 2 + 50], [width, height], [0, height]]) dst = np.float32([[0, 0], [width, 0], [width, height], [0, height]]) M = cv2.getPerspectiveTransform(src, dst) warped = cv2.warpPerspective(frame, M, (width, height)) return warped ``` 在`lane_detection`函数中调用该函数: ```python def lane_detection(video_path, output_path): frames = read_frames(video_path) processed_frames = [] for frame in frames: warped_frame = perspective_transform(frame) masked_frame = apply_mask(warped_frame) thresh_frame = thresholding(masked_frame) lines = hough_lines(thresh_frame) frame_with_lines = draw_lines(frame.copy(), lines) processed_frames.append(frame_with_lines) frames_to_video(processed_frames, output_path) ``` #### 2. 机器学习方法 结合机器学习算法,如支持向量机(SVM)或随机森林,对车道线进行更准确的检测和分类。可以使用提取的特征(如颜色、梯度等)训练模型,然后使用模型进行车道线检测。 #### 3. 线段合并 将相邻的短线段合并为更长的线段,减少检测结果中的噪声和不连续线段。可以通过计算线段之间的距离和角度,将符合条件的线段合并。 #### 4. 参数优化 调整霍夫变换等算法的参数,根据不同的场景和视频质量,找到最优的参数组合,提高检测的准确性和鲁棒性。可以使用网格搜索或随机搜索等方法进行参数优化。 #### 5. 实时处理优化 采用多线程或并行计算的方式,提高代码的实时处理能力,减少处理延迟。例如,可以使用 Python 的`concurrent.futures`模块实现多线程处理。 ### 代码运行中可能出现的问题及解决办法 #### 1. 视频文件无法打开 可能是视频文件路径错误或文件损坏。检查视频文件路径是否正确,尝试使用其他视频文件进行测试。 #### 2. 霍夫线变换检测不到直线 可能是阈值参数设置不合理。调整`threshold`、`min_length`和`max_gap`等参数,找到合适的值。 #### 3. 车道线检测不准确 可能是图像预处理步骤效果不佳。检查掩码区域是否正确,调整阈值化参数,或者尝试使用其他图像增强方法。 #### 4. 视频合并失败 可能是输出路径没有写入权限或视频编码器不支持。检查输出路径是否可写,尝试使用其他视频编码器(如`*'XVID'`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鼠晓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值