OpenCV对图像像素尺寸的设置

OpenCV对视频流图像像素尺寸的设置问题

项目场景:在opencv读取视频流时对输入图像的尺寸进行任意设置

问题描述:

在使用opencv处理视频流时,通常要对读取到的图像进行尺寸设置,以便于后续图像处理和算法设计。OpenCV读取视频的类VideoCapture的接口函数VideoCapture::set(int id,double value)可以对图像尺寸进行设置。但当我们随意设置一个尺寸后,再输出图像的行和列,会发现输出的行列和我们设置的行列并不同。如有下列程序:

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
	//当主机只连接一个摄像头时默认编号为0
	VideoCapture cap(0);
	//想要得到大小为780×460的图像
	cap.set(CAP_PROP_FRAME_WIDTH, 780);
	cap.set(CAP_PROP_FRAME_HEIGHT, 460);
	while(1)
	{
		Mat orgImage;
		cap >> orgImage;
		cout << "图像行为: " << orgImage.rows << "\n" << "图像列为: " << orgImage.cols << endl;
		//摄像头断开连接时程序结束
		if (orgImage.empty())
			break;
	}
	return 0}

这时我们期待输出为:
图像行为:460
图像列为:780
但实际上输出为:

图像行为:448
图像列为:800

原因分析:

产生这种结果是因为,set()设置的像素尺寸并不是有无限多种,而是只在其规定的几种尺寸里(可以人为它有一个尺寸容器,容器里只包含若干个尺寸供人们选择)选择输出,输出的最终结果基于我们人为在set里填写的数字大小,根据我们输入的尺寸,在“尺寸容器”中选择最接近的一个尺寸作为图像的实际输出尺寸。例如默认尺寸为(default_width, default_height),而我们设置的尺寸为(input_width, input_height),这时会选择满足(|input_width-default_width|+|input_height-default_height|)值最小的默认的一对尺寸成为最终输出尺寸。
经本人测试,set()函数只有11种像素尺寸,分别为:

(160,120);(320,240);(352,288);
(424,240);(640,360);(640,480);
(800,448);(800,600);(960,544);
(1280,720);(1920,1080);

现在可以回答一开始的问题,当我们设置尺寸为(780,460),按上述公式计算(800,448)这组默认尺寸满足最小值要求,所以输出尺寸为(800,448)。

解决方案:

那么如果我们就是想要默认尺寸里没有的某个任意像素尺寸呢?opencv里还有一个函数就可以解决这个问题,即resize()函数。其函数原型为:

CV_EXPORTS_W void resize( InputArray src, OutputArray dst,Size dsize, double fx=0, 
                          double fy=0,int interpolation=INTER_LINEAR );

其中src为输入图像;
dst为尺寸改变后的输出图像;
dsize为输出尺寸,当输入为0时,fx、fy不可均为0,dsize = Size(round(fxsrc.cols),round(fysrc.rows));
fx为水平缩放比例,当输入为0时,fx=(double)dsize.width/src.cols;
fy为垂直缩放比例,当输入为0时,fy=(double)dsize.height/src.rows;
interpolation为内插方式,内插方式有:
a). CV_INTER_NEAREST 最邻近插值点法
b). CV_INTER_LINEAR 双线性插值法
c).CV_INTER_AREA 邻域像素再取样插补
d).CV_INTER_CUBIC 双立方插补,4*4大小的补点
所以,通过set()resize()的搭配使用就可以设置任意大小的图像尺寸,如我想得到一个400×400的图像,即可通过如下代码实现:

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
	//当主机只连接一个摄像头时默认编号为0
	VideoCapture cap(0);
	//想要得到大小为780×460的图像
	cap.set(CAP_PROP_FRAME_WIDTH, 800);
	cap.set(CAP_PROP_FRAME_HEIGHT, 600);
	while(1)
	{
		Mat orgImage, dstImage;
		cap >> orgImage;
		//摄像头断开连接时程序结束
		if (orgImage.empty())
			break;
		resize(orgImage, dstImage, Size((int)(orgImage.cols*0.5), (int)(orgImage.rows*0.667)));
		cout << "图像行为: " << dstImage.rows << "\n" << "图像列为: " << dstImage.cols << endl;
	}
	return 0}

此时输出即为:

图像行为:400
图像列为:400
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值