图像处理基础及OpenCV实现(二)

本文深入探讨了图像处理中常见的几何变换技术,包括图像缩放、旋转等操作,并详细介绍了OpenCV库中的相关函数,如cvResize和cvWarpAffine,以及如何应用这些函数进行图像的缩放和旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二、图像的几何变换

1、 图像缩放

图像缩放需要使用插值,图像插值通常有三种方式:最近邻插值、双线性插值、双立方插值。

OpenCV提供的函数:
函数
IplImage* cvCreateImage(CvSize size,int depth,int channels) 创建一幅图像并返回存储图像的首地址。
参数CvSize cvSize( int width, int height ) 图像的高宽
参数depth,表示图像的量化深度

#define IPL_DEPTH_1U     1
#define IPL_DEPTH_8U     8
#define IPL_DEPTH_16U   16
#define IPL_DEPTH_32F   32
#define IPL_DEPTH_8S  (IPL_DEPTH_SIGN| 8)
#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16)
#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32)

参数 channels 表示图像的通道

函数 void cvResize( const CvArr* src, CvArr* dst, int interpolation CV_DEFAULT( CV_INTER_LINEAR ))
参数 src 原图像首地址
参数 dst 目的图像首地址
参数 interpolation 表示缩放的插值方式
CV_INTER_NN =0, 最近邻插值
CV_INTER_LINEAR =1, 双线性插值
CV_INTER_CUBIC =2, 立方插值
CV_INTER_AREA =3, 基于像素区域关系
CV_INTER_LANCZOS4 =4 兰索斯插值

代码如下:

IplImage* dst = cvCreateImage(cvSize(nWidth, nHeight), IPL_DEPTH_8U, 3);
cvResize(m_ipl, dst, CV_INTER_LINEAR);
cvNamedWindow("缩放后图像");
cvShowImage("缩放后图像", dst);
cvWaitKey(0);
cvReleaseImage(&dst);

2、图像旋转

图像的几何变换可以看作原图像的每个像素点乘以一个变换矩阵:
在这里插入图片描述

在这里插入图片描述
表示旋转变换。
在这里插入图片描述
表示平移变换。

仿射变换函数(void) cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS), CvScalar fillval CV_DEFAULT(cvScalarAll(0)) )
参数src 表示原图像
参数 dst 表示输出图像
参数 map_matrix表示变换矩阵;CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))
参数flags 默认插值方式与填充方式
参数 fillval 填充边界外的值

确定图像旋转后的外接矩形的边界大小,如下图:
在这里插入图片描述
在这里插入图片描述
注意:上述旋转变换是以左上角为中心逆时针旋转,在旋转过程中会出现图像坐标为负的情况,如下图:
在这里插入图片描述
解决方案:
1、 用库函数将旋转中心换至图像中心,再进行调整。
用到函数:
(CvMat*) cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* map_matrix );
参数 center表示重新设定图像旋转中心,用cvPoint2D32f(width / 2, height / 2)将旋转点设置为图像中心
参数 angle 表示旋转的角度
参数 scale 表示缩放的倍率
参数 map_matrix 返回变换矩阵
2、 直接将旋转后的图像平移
通过几何计算可以得到,比较繁琐,下面直接给出相关代码:

ca = (float)cos((double)(nAngle)*CV_PI / 180);
sa = (float)sin((double)(nAngle)*CV_PI / 180);
// 获取图像高宽
nx = m_ipl->width;
ny = m_ipl->height;

// 设置旋转后图像的大小
sx = nx*fabs(sa) + ny*fabs(ca) + 1;
sy = nx*fabs(ca) + ny*fabs(sa) + 1;

// 根据旋转角度来确定平移量
if ((nAngle % 360) <= 90)
{
	xleft = 0;
	ydown = nx*sa;
}
else if ((nAngle % 360) > 90 && (nAngle % 360) <= 180)
{
	xleft = -nx*ca;
	ydown = nx*sa - ny*ca;
}
else if ((nAngle % 360) > 180 && (nAngle % 360) <= 270)
{
	xleft = -ny*sa-nx*ca;
	ydown = -ny*ca;
}
else
{
	xleft = -ny*sa;
	ydown = 0;
}

// 创建输出图像
IplImage* dst;
dst = cvCreateImage(cvSize(sx, sy), m_ipl->depth, m_ipl->nChannels);
// 设定变换矩阵
float m[6] = { ca,sa,(float)xleft,-sa,ca,(float)ydown };
CvMat M = cvMat(2, 3, CV_32F, m);
// 衍射变换
cvWarpAffine(m_ipl, dst, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));

cvNamedWindow("旋转后的图像");
cvShowImage("旋转后的图像", dst);
cvWaitKey(0);
cvReleaseImage(&dst);

程序结果如下:
在这里插入图片描述

图像处理领域中,OpenCV是一个开源的计算机视觉和机器学习软件库,它提供了很多在图像和视频分析上的功能。图像的边界填充是指对图像边缘进行扩展,并对扩展部分赋予一定的值,这样在对图像进行卷积操作等过程中可以避免边界效应。 在OpenCV中,边界填充可以通过`cv2.copyMakeBorder()`函数来实现。该函数可以将源图像复制到新图像中,并在源图像的四周根据设定的参数进行边界填充。填充参数包括边界类型、边界的宽度以及填充的颜色值等。 边界填充类型主要分为以下几种: - `BORDER_CONSTANT`:使用固定值进行填充。 - `BORDER_REFLECT`:边界反射填充。 - `BORDER_REFLECT_101` 或 `BORDER_DEFAULT`:边界反射填充,但左右对称。 - `BORDER_REPLICATE`:复制最边缘的值。 - `BORDER_WRAP`:周期性填充。 以下是一个简单的示例代码,展示了如何使用`copyMakeBorder`函数进行边界填充: ```python import cv2 import numpy as np # 读取一张图片 image = cv2.imread('example.jpg') # 设置边界填充的参数 top, bottom, left, right = 10, 10, 10, 10 border_type = cv2.BORDER_CONSTANT value = (255, 255, 255) # 白色填充 # 执行边界填充 extended_image = cv2.copyMakeBorder(image, top, bottom, left, right, border_type, value=value) # 显示原图和填充后的图像 cv2.imshow('Original image', image) cv2.imshow('Extended image', extended_image) cv2.waitKey(0) cv2.destroyAllWindows() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值