利用opencv怎样旋转一幅图像

该文详细介绍了图像旋转的过程,包括坐标系转换,以旋转中心为原点进行旋转,以及如何确定旋转后图像的新尺寸。使用OpenCV库,通过构建旋转矩阵并应用坐标变换,实现了图像的旋转功能。代码示例展示了如何在C++中执行这一操作。

图像旋转是指图像按照某个位置转动一定角度的过程,旋转中图像仍保持着原始尺寸。图像旋转后图像的水平对称轴、垂直对称轴以及中心坐标原点可能都会发生变换,因此需要对图像旋转中的坐标进行相应的转换

图像坐标构成

 

 

解释一下上面的各个步骤

由于图像坐标是以左上角为原点,向右为X正方向,向下为Y正方向。而旋转时一般使用的是常见的笛卡尔坐标系,向右为X正方向,向上为Y正方向。所以进行旋转变换的第一步就是坐标系转换。第一步先解释坐标系转换的过程。

 

 第二步解释旋转的过程

 

在进行图像旋转的过程中,图像以旋转中心为坐标原点,最终完成旋转还需要将坐标原点移动到图像的左上角。旋转后图像的尺寸可以由图像极值点确定,设旋转后图像的最左边点的横坐标为lxmin,最右边的横坐标为lxmax,最高点的纵坐标为lymin,最低点的纵坐标为lymax.

 

最后需要将坐标原点变换到旋转后图像的左上角坐标,根据旋转前后的坐标转换可得左上角坐标为,矩阵表示为:

 

 

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;

Mat angleRotate(Mat& src, int angle)
{
	//角度转换
	float alpha = angle * CV_PI / 180;
	//构造旋转矩阵
	float rotateMat[3][3] = {
		{cos(alpha),-sin(alpha),0},
		{sin(alpha),cos(alpha),0},
		{0,0,1} };
	int nSrcRows = src.rows;
	int nSrcCols = src.cols;

	//计算旋转后图像矩阵的各个顶点位置
	float a1 = nSrcCols * rotateMat[0][0];
	float b1 = nSrcCols * rotateMat[1][0];
	float a2 = nSrcCols * rotateMat[0][0] + nSrcRows * rotateMat[0][1];
	float b2 = nSrcCols * rotateMat[1][0] + nSrcRows * rotateMat[1][1];
	float a3 = nSrcRows * rotateMat[0][1];
	float b3 = nSrcRows * rotateMat[1][1];
	//计算出极值点
	float kxMin = min(min(min(0.0f, a1), a2), a3);
	float kxMax = max(max(max(0.0f, a1), a2), a3);
	float kyMin = min(min(min(0.0f, b1), b2), b3);
	float kyMax = max(max(max(0.0f, b1), b2), b3);
	//计算输出矩阵的尺寸
	int nRows = abs(kyMax - kyMin);
	int nCols = abs(kxMax - kxMin);
	Mat dst(nRows, nCols, src.type(), Scalar::all(0));
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			//旋转坐标变换
			int x = (j + kxMin) * rotateMat[0][0] - (i + kyMin) * rotateMat[0][1];
			int y = -(j + kxMin) * rotateMat[1][0] +(i + kyMin) * rotateMat[1][1];
			//区域旋转
			if (x >= 0 && x < nSrcCols && y >= 0 && y < nSrcRows)
			{
				dst.at<Vec3b>(i, j) = src.at<Vec3b>(y, x);
			}
		}
	}
	return dst;
}
int main()
{
	Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
	if (!src.data)
	{
		return -1;
	}
	imshow("src", src);
	int angle = 30;
	Mat result = angleRotate(src, angle);
	imshow("result",result);
	waitKey();
	return 0;

}

运行程序结果如下: 

### 使用 OpenCV 读取彩色图像并获取其基本信息 在 Python 中,可以利用 OpenCV 库来高效地读取彩色图像,并进一步获取图像的尺寸、通道数和像素值。以下是具体方法: #### 1. 导入库 首先需要导入 `cv2` 和其他可能用到的库(如 NumPy),以便后续操作。 ```python import cv2 import numpy as np ``` #### 2. 读取彩色图像 使用 `cv2.imread()` 函数可以从文件路径加载一张图片。默认情况下,此函数将以 BGR 格式读取彩色图像[^1]。 ```python image_path = 'example.jpg' # 替换为实际图像路径 img = cv2.imread(image_path) if img is None: print("无法读取图像,请检查路径是否正确") else: print("成功读取图像") ``` #### 3. 获取图像尺寸 可以通过 `.shape` 属性获得图像的高度、宽度和通道数。返回的结果是一个元组 `(height, width, channels)`,其中第三个参数仅适用于多通道图像(如彩色图像)。如果图像是灰度图像,则只有两个维度 (高度和宽度)[^4]。 ```python dimensions = img.shape print(f"图像尺寸: 高度={dimensions[0]} 像素, 宽度={dimensions[1]} 像素") channels = dimensions[2] if len(dimensions) == 3 else 1 print(f"通道数量: {channels}") ``` #### 4. 访问单个像素值 要访问某个特定位置的像素值,可以直接通过数组索引来完成。例如,`img[y,x]` 返回位于第 y 行 x 列处的颜色向量;如果是三通道图像,则返回 `[B,G,R]` 形式的列表[^4]。 ```python pixel_value_bgr = img[100, 150] # 获取(100,150)坐标的BGR值 print(f"(100,150) 处的BGR值: {pixel_value_bgr}") blue_channel = pixel_value_bgr[0] green_channel = pixel_value_bgr[1] red_channel = pixel_value_bgr[2] print(f"B通道值: {blue_channel}, G通道值: {green_channel}, R通道值: {red_channel}") ``` 需要注意的是,在 OpenCV 中,默认采用 BGR 色彩空间而非标准 RGB 排序[^3]。 #### 5. 修改指定像素值 同样也可以修改某一点的像素值,只需重新赋值即可。 ```python img[100, 150] = [255, 0, 0] # 将(100,150)设置成纯蓝色(B=255,G=0,R=0) updated_pixel = img[100, 150] print(f"更新后的(100,150)像素值: {updated_pixel}") ``` 上述过程展示了如何基于 OpenCV 实现对彩色图像的基本操作,包括但不限于读取、查询大小信息以及调整个别像素点的内容。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值