OpenCV 图片的读取(imread和imdecode)、(并排)显示与保存(imwrite和imencode)
前言
C++和python两者的使用语法都是相同的
一、读取(imread和imdecode)
1、imread
由两个参数决定:
imread(“图片的地址+名称”, 何种形式读取图片)
第二个参数,可以使用标志参数,也可以使用简记数字。常用的就是
读取形式 标志参数 简记数字 以原图读取(针对有Alpha通道的图片) IMREAD_UNCHANGED 1 以单通道的灰度图像读取 IMREAD_GRAYSCA 0 以3通道BGR的彩色图片读取 IMREAD_COLOR 12、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)销毁窗口
注:如果原图分辨率太大,显示不完全怎么办? 使用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 数组的一个方法,用于将数组中的数据以二进制形式写入文件):
总结
imdecode和imencode是进行与内存缓冲区之间的操作(而不是磁盘),在某些场景下更加高效,但C++中使用这两个比较繁琐,python中使用较为方便。
上一篇:数控系统中的模态指令
OpenCV