当前位置: 首页 > 网络知识

OpenCV 图片的读取(imread和imdecode)、(并排)显示与保存(imwrite和imencode)

时间:2026-01-29 09:26:17

前言

  C++和python两者的使用语法都是相同的

一、读取(imread和imdecode)

1、imread

  由两个参数决定:
  imread(“图片的地址+名称”, 何种形式读取图片)

1 image = cv2.imread("C:/Opencv/lena.jpg", cv2.IMREAD_GRAYSCA) // python 2 cv::Mat image = cv::imread("C:/Opencv/lena.jpg", 0); // c++

第二个参数,可以使用标志参数,也可以使用简记数字。常用的就是

读取形式 标志参数 简记数字 以原图读取(针对有Alpha通道的图片) IMREAD_UNCHANGED 1 以单通道的灰度图像读取 IMREAD_GRAYSCA 0 以3通道BGR的彩色图片读取 IMREAD_COLOR 1

2、imdecode
  imread是从文件(磁盘)中直接读取图像数据,imdecode是从内存缓冲区中读取数据,并解码成图像格式。

  使用imdecode的优点在于可以从内存中直接解码图像数据,而不需要将数据保存到磁盘再进行读取。在某些场景中是有用的,如网络传输的数据源,摄像头捕获的图像数据。

  imdecode与image的使用有一点要注意:imread是传入图片路径,转为图片格式;imdecode传入的内存数据(数组形式),转为图片格式。就以上面的简单例子:从文件中读取图片。imdecode的python写法可以为下:

1 # 使用 NumPy 的 frfile 函数从指定路径中读取图像数据,并将其存储为 NumPy 数组,作为参数传给imdecode解码成图像格式 2 image = cv2.imdecode(np.frfile("C:/Opencv/lena.jpg", dtype = np.uint8), 1) # 1为标志参数,3通道读取

  注:一般情况下,读取图像的像素数目小于2^30,这个要求在绝大多数图像处理领域都是不受影响的,但是对于超高分辨率图像的像素数目可能会超过这个阈值,可以通过修改系统变量中的OPENCV_IO_MAX_IMAGE_PIXELS参数调整能够读取的最大像素数目。

二、显示(imshow)
  显示图片一般调试时使用,没有什么特别注意的(反正最终结果也要将其注释掉)。
  常用三件套:1)显示图片窗口 2)窗口的持续时间或阻塞 3)销毁窗口

1 cv::imshow("Show", image); // "Show"是显示窗口的名称,image是读取的图片 2 //cv::waitKey(300) // 窗口持续300ms后关闭,继续后续程序 3 cv::waitKey(0); // 0 将会一直阻塞程序的执行,直到用户按下键盘上的任意键 4 cv::destroyAllWindows(); // 关闭程序中所有的窗口,一般用于程序的最后

注:如果原图分辨率太大,显示不完全怎么办? 使用namedWindow()这个窗口函数设置一下。

此外,某些场景下想让图片并排表示,来更好的对比效果,可以使用以下方式(仅当展示图片的尺寸相同时):

1 cv::Mat img = cv::imread("C:/Users/20231.jpg"); 2 cv::Mat img1 = cv::imread("C:/Users/3353S020730_WA.jpg"); 3 cv::Mat img2 = cv::imread("C:/Users/3014353S020730_WA.jpg"); 4 5 // 获取每张图像的大小 6 int h = img.rows; 7 int w = imgols; 8 int h1 = img1.rows; 9 int w1 = img1ols; 10 int h2 = img2.rows; 11 int w2 = img2ols; 12 13 // 创建一个大画布用于展示三张图像 14 cv::Mat canvas(std::max(h, std::max(h1, h2)), w + w1 + w2, CV_8UC3, cv::Scalar(0, 0, 0)); 15 16 // 将三张图像放置在合适的位置上 17 imgopyTo(canvas(cv::Rect(0, 0, w, h))); 18 img1opyTo(canvas(cv::Rect(w, 0, w1, h1))); 19 img2opyTo(canvas(cv::Rect(w + w1, 0, w2, h2))); 20 21 cv::imshow("Merged Images", canvas); 22 cv::waitKey(0); 23 cv::destroyAllWindows();

python代码如下:

1 img = cv2.imread("img.jpg") 2 img1 = cv2.imread("img1.jpg") 3 img2 = cv2.imread("img2.jpg") 4 5 # 获取每张图像的大小 6 h, w, _ = img.shape 7 h1, w1, _ = img1.shape 8 h2, w2, _ = img2.shape 9 10 # 创建一个大画布用于展示三张图像 11 canvas = np.zeros((max(h, h1, h2), w + w1 + w2, 3), dtype=np.uint8) 12 13 # 将三张图像放置在合适的位置上 14 canvas[:h, :w] = img 15 canvas[:h1, w:w+w1] = img1 16 canvas[:h2, w+w1:] = img2 17 18 # 显示合并后的图像 19 cv2.imshow("Merged Images", canvas) 20 cv2.waitKey(0) 21 cv2.destroyAllWindows()

三、保存(imwrite和imencode)

1、imwrite

与读取imread相似,要给出具体保存的路径(地址+图片名)

1 cv::Mat image = cv::imread("C:/Opencv/lena.jpg", cv::IMREAD_GRAYSCALE); 2 cv::imwrite("C:/Opencv/temp/lena.jpg", image);

  值得注意的是批量图片的保存。通常方法都是 :(固定的文件夹地址)+(流动的图片名)

  ( 注:imwrite函数还有第三个参数,用于保存不同格式的图像。如果保存的图像是单通道或三通道,那第三个参数可以忽略。但如果保存的是特殊格式(如16位深度图像),则需要设置第三个参数。)

2、imencode
  imencode函数是将图像数据编码成流数据(如png格式,jpg格式),返回的是一个元组(bool,NumPy),第一个元素是布尔值,表示编码是否成功;第二个是编码后的数据——NumPy数组。若想把数据保存到文件中,还需要其他步骤,例如,python中使用.tofile(.tofile() 是 NumPy 数组的一个方法,用于将数组中的数据以二进制形式写入文件):

1 image = cv2.imdecode(np.frfile("C:/Opencv/lena.jpg", dtype = np.uint8), 1) 2 cv2.imencode('.png', image)[1].tofile("C:/Opencv/temp/ena.png") // 索引[1]取出元组中的第二个元素,即编码后的图像数据

总结

  imdecode和imencode是进行与内存缓冲区之间的操作(而不是磁盘),在某些场景下更加高效,但C++中使用这两个比较繁琐,python中使用较为方便。



上一篇:联想屏幕亮度调节失灵(已解决)
下一篇:MATLAB 2022b 图文安装保姆级教程|Matlab密匙|激活步骤|
OpenCV
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素