基于CSV数据生成大尺寸单色纹理图像的性能优化与实现问题
使用OpenCV基于CSV生成大尺寸单色纹理图的优化方案
问题背景
需要基于CSV数据(含X/Y像素坐标、圆半径R,共约55000行)生成最小尺寸为2800px×57000px的单色填充圆纹理图(不可拆分),初始用OpenCV实现时速度极慢(约每行耗时1秒),需解决以下两个问题:
- 不更换开发语言的前提下提升执行速度
- 将图像转为单色并优化存储
1. 执行速度优化方案
核心瓶颈分析
原代码的最大性能问题是在循环内重复调用cv2.imwrite():每次循环都要完成磁盘IO和图像编码,这会导致大量不必要的开销,是速度慢的主要原因。
优化步骤
- 将
cv2.imwrite()移出循环,仅在所有圆绘制完成后执行一次写入 - 移除循环内的
print(row)操作(打印会拖慢循环执行速度) - 用
next(Data)直接跳过CSV表头,替代冗余的count判断 - 修正Windows路径的转义问题(使用双反斜杠或原始字符串)
优化后代码
import cv2 import numpy as np import datetime import csv # 创建单通道空白图(提前适配单色需求) Img = np.zeros((57000, 2800), np.uint8) # 读取CSV(注意路径转义) with open(r'C:\Temp\OPENCV.csv', newline='') as csvfile: Data = csv.DictReader(csvfile) next(Data) # 跳过表头行 window_name = 'Preview' print("Start: " + str(datetime.datetime.now())) for row in Data: # 解析坐标和半径 center_coordinates = (int(row['X']), int(row['Y'])) radius = int(row['R']) color = 255 # 单通道白色 thickness = -1 # 填充圆 # 绘制圆 cv2.circle(Img, center_coordinates, radius, color, thickness) # 仅执行一次写入 cv2.imwrite(r'C:\Temp\CVTest.png', Img, [cv2.IMWRITE_PNG_BILEVEL, 1]) print("End: " + str(datetime.datetime.now())) # 预览图像(可选) cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) # 用WINDOW_NORMAL适配大尺寸图像 cv2.imshow(window_name, Img) cv2.waitKey(0) cv2.destroyAllWindows()
优化效果
将cv2.imwrite()移出循环后,整个图像生成仅需约2秒,性能提升显著。
2. 单色图像实现与存储优化
方案一:OpenCV原生实现
- 创建图像时使用单通道数组:
np.zeros((57000, 2800), np.uint8),而非3通道的RGB数组 - 保存时添加
[cv2.IMWRITE_PNG_BILEVEL, 1]参数,强制生成二值化PNG图像
方案二:PIL优化存储(更小文件体积)
通过PIL将图像转为1位深度的二值图,能进一步压缩文件体积:
from PIL import Image import cv2 # 假设Img是OpenCV生成的单通道图像 img_rgb = cv2.cvtColor(Img, cv2.COLOR_GRAY2RGB) # 转换为RGB格式适配PIL im_pil = Image.fromarray(img_rgb) im_pil.save(r'C:\Temp\CVTest2.png', bits=1, optimize=True)
效果对比
- OpenCV原生方案生成的文件:2687KB
- PIL优化方案生成的文件:1188KB
内容的提问来源于stack exchange,提问作者G.H.
相关产品推荐
相关产品推荐

