图像旋转 c++/python实现

19 篇文章 6 订阅
9 篇文章 0 订阅
#include <iostream>
#include <string.h>   
#include <math.h>       
#include <stdlib.h>     
#include <malloc.h>  
#include <cstdio>
#include "bmp.h"
using namespace std;
#define DRAW_HEIGHT 400  //目标图像高度  
#define DRAW_WIDTH 400  //目标图像宽度  
#define pi 3.1415926535
int main()
{
    BMP rbmp;
    BMP wbmp(DRAW_WIDTH,DRAW_HEIGHT);
	char strFile[50] = "./lena24.bmp";//打开图像路径,BMP图像必须为24位真彩色格式  
	char strFilesave[50] = "./test.bmp";//处理后图像存储路径 
    //读取位图的数据 
    imread(strFile,rbmp);
    int width = rbmp.cols();
	int height = rbmp.rows(); 
	int l_width = WIDTHBYTES(width*24);//计算位图的实际宽度并确保它为4byte的倍数  
    //写位图的数据
    int write_width = WIDTHBYTES(DRAW_WIDTH*24);//计算写位图的实际宽度(字节)并确保它为4byte的倍数   

	/*******************图像处理部分******************/
    int centerofrotation_x = DRAW_WIDTH / 2;//旋转中心x坐标
	int centerofrotation_y = DRAW_HEIGHT / 2;//旋转中心y坐标
	double degree = 60;//逆时针旋转角度
	double radian = degree / 180 * pi;//角度转弧度
	for (int hnum = 0; hnum < DRAW_HEIGHT; hnum++)
	{
    for (int wnum = 0; wnum < DRAW_WIDTH; wnum++)
	{
        int pixel_point = hnum*write_width + wnum * 3;//映射尺度变换图像数组位置偏移量
 
		double d_original_img_wnum = (wnum - centerofrotation_x)*cos(radian) - (hnum - centerofrotation_y)*sin(radian) + centerofrotation_x;
		double d_original_img_hnum = (wnum - centerofrotation_x)*sin(radian) + (hnum - centerofrotation_y)*cos(radian) + centerofrotation_y;
 
		if (d_original_img_wnum<0 || d_original_img_wnum>width || d_original_img_hnum<0 || d_original_img_hnum>height)//找不到与原图像的对于关系
		{
			wbmp.pColorData[pixel_point] = wbmp.pColorData[pixel_point + 1] = wbmp.pColorData[pixel_point + 2] = 0;
			continue;
		}
 
		int i_original_img_hnum = d_original_img_hnum;
		int i_original_img_wnum = d_original_img_wnum;
		double distance_to_a_x = d_original_img_wnum - i_original_img_wnum;//在原图像中与a点的水平距离
		double distance_to_a_y = d_original_img_hnum - i_original_img_hnum;//在原图像中与a点的垂直距离
 
		int original_point_a = i_original_img_hnum*l_width + i_original_img_wnum * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点A  
		int original_point_b = i_original_img_hnum*l_width + (i_original_img_wnum + 1) * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点B
		int original_point_c = (i_original_img_hnum + 1)*l_width + i_original_img_wnum * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点C 
		int original_point_d = (i_original_img_hnum + 1)*l_width + (i_original_img_wnum + 1) * 3;//数组位置偏移量,对应于图像的各像素点RGB的起点,相当于点D 
		if (i_original_img_hnum == DRAW_HEIGHT - 1)
		{
			original_point_c = original_point_a;
			original_point_d = original_point_b;
		}
		if (i_original_img_wnum == DRAW_WIDTH - 1)
		{
			original_point_a = original_point_b;
			original_point_c = original_point_d;
		}
 
		wbmp.pColorData[pixel_point] =
			rbmp.pColorData[original_point_a] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_b] * distance_to_a_x*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_c] * distance_to_a_y*(1 - distance_to_a_x) +
			rbmp.pColorData[original_point_c] * distance_to_a_y*distance_to_a_x;
		wbmp.pColorData[pixel_point + 1] =
			rbmp.pColorData[original_point_a + 1] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_b + 1] * distance_to_a_x*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_c + 1] * distance_to_a_y*(1 - distance_to_a_x) +
			rbmp.pColorData[original_point_c + 1] * distance_to_a_y*distance_to_a_x;
		wbmp.pColorData[pixel_point + 2] =
			rbmp.pColorData[original_point_a + 2] * (1 - distance_to_a_x)*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_b + 2] * distance_to_a_x*(1 - distance_to_a_y) +
			rbmp.pColorData[original_point_c + 2] * distance_to_a_y*(1 - distance_to_a_x) +
			rbmp.pColorData[original_point_c + 2] * distance_to_a_y*distance_to_a_x;
 
	}
    }
	/*******************图像处理部分******************/
    std::cout<<"Done!"<<std::endl;
    imwrite(strFilesave,wbmp); 
    system("pause"); 
    return 0;
}

效果图:
在这里插入图片描述
在这里插入图片描述
一般情况下,图像的旋转和图像轮廓最小外接矩阵一起使用,可以将最小外接矩阵变为正放着的。
opencv-python代码:

def rotateRect(img, rect):
    (x, y) = rect[0]
    angle = rect[2]
    width, height = rect[1]
    # 外接矩形中心点坐标
    rot_mat = cv2.getRotationMatrix2D((x, y), angle, 1)
    # 求旋转矩阵
    (w, h) = img.shape[:2]
    rot_image = cv2.warpAffine(img, rot_mat, (h, w))
    # 原图像旋转
    result = rot_image[int(y - (height/2)):int(y+(height/2)),
                       int(x - (width / 2)): int(x + (width / 2))]
    if(len(result.shape)==2 and result.shape[0]>result.shape[1]):
        result = result.transpose((1,0))
    if(len(result.shape)==3 and result.shape[0]>result.shape[1]):
        result = result.transpose((1,0,2))
    return result
if __name__ == "__main__": 
    img2,contours,hierarchy=cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for i in range(len(contours)):
        rect = cv2.minAreaRect(contours[i])  # 最小外接矩形
        rotateRect(img, rect)

效果如下所示:
原图:
在这里插入图片描述
旋转后:
在这里插入图片描述
旋转后的图片是正放着的矩阵,可以在上面进行操作,画出鱼的长度了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值