#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)
效果如下所示:
原图:
旋转后:
旋转后的图片是正放着的矩阵,可以在上面进行操作,画出鱼的长度了。