(一)基础知识
(1)常见图片几何运算
图像的几何变换主要就是一下这些。
这里只是一些最简单的函数处理
·图像的平移变换
·图像的镜像变换
·图像的转置变换
·图像的旋转变换
·图像的缩放
这里我主要实现了平移和旋转
(2)图像平移算法分析
(3)图像旋转算法分析
这里一旋转30度为例
注意:为了实现图片的旋转有的时候一定会产生空白点,为了是图像变得自然必须进行图像的插值处理。
(二)程序设计
图像的平移和旋转的实现并不是十分难以理解
GeoTrans.c
/*
*版权所有 (C)2019,Yueyang.
*文件名称:GeoTrans.c
*内容摘要:LiteCV几何变换
*当前版本:V1.0
*作者:杨越
*完成日期:20191020
*/
#include "cv.h"
#include "bmp.h"
#include "GeoTrans.h"
#include <math.h>
#include <stdio.h>
void PointSwap(u8* inaddr,u8* outaddr)
{
*inaddr=*outaddr;
*(inaddr+1)=*(outaddr+1);
*(inaddr+2)=*(outaddr+2);
}
Mat imrotate(Mat mat,int Angle)
{
u8* inaddr;
u8* outaddr;
double angle;//要旋转的弧度数
int step = 0;
int Rot_step = 0;
int i, j;
int midX_pre,midY_pre,midX_aft,midY_aft;//旋转前后的中心点的坐标
int pre_i,pre_j,after_i,after_j;//旋转前后对应的像素点坐标
angle = 1.0 * Angle * PI / 180;
Mat out=copy(mat);
for ( i = 0; i < mat.width; i++)
{
for ( j = 0; j < mat.highth; j++)
{
inaddr=at(&out,i,j);
*inaddr=0x00;
*(inaddr+1)=0x00;
*(inaddr+2)=0x00;
}
}
//坐标变换
for(i = 0;i < mat.highth;i++)
{
for(j = 0;j < mat.width;j++)
{
after_i = i;
after_j = j;
pre_i = (int)(cos((double)angle) * after_i - sin((double)angle) * after_j) + mat.width/2-90;
pre_j = (int)(sin((double)angle) * after_i + cos((double)angle) * after_j)-30;
inaddr=at(&out,after_i,after_j);
outaddr=at(&mat,pre_i,pre_j);
if(pre_i<mat.width&&pre_j<mat.highth&&pre_j>=0&&pre_i>=0)
PointSwap(inaddr,outaddr);
}
}
return out;
}
//DIR:0左 1右 2上 3 下
//distance 移动的像素距离
Mat immove(Mat mat,int dir,int distance)
{
u8* inaddr;
u8* outaddr;
Mat out=copy(mat);
int i,j,x,y;
for ( i = 0; i < mat.width; i++)
{
for ( j = 0; j < mat.highth; j++)
{
inaddr=at(&out,i,j);
*inaddr=0x00;
*(inaddr+1)=0x00;
*(inaddr+2)=0x00;
}
}
switch (dir)
{
case 1:
for ( i = distance; i < mat.width; i++)
{
for ( j = 0; j < mat.highth; j++)
{
inaddr=at(&out,i-distance,j);
outaddr=at(&mat,i,j);
PointSwap(inaddr,outaddr);
}
}
break;
case 0:
for ( i = 0; i < mat.width-distance; i++)
{
for ( j = 0; j < mat.highth; j++)
{
inaddr=at(&out,i+distance,j);
outaddr=at(&mat,i,j);
PointSwap(inaddr,outaddr);
}
}
break;
case 3:
for ( i = 0; i < mat.width; i++)
{
for ( j = distance; j < mat.highth; j++)
{
inaddr=at(&out,i,j);
outaddr=at(&mat,i,j-distance);
PointSwap(inaddr,outaddr);
}
}
break;
case 2:
for ( i = 0; i < mat.width; i++)
{
for ( j = 0; j < mat.highth-distance; j++)
{
inaddr=at(&out,i,j);
outaddr=at(&mat,i,j+distance);
PointSwap(inaddr,outaddr);
}
}
break;
default:
break;
}
return out;
}
GeoTrans.h
/*
*版权所有 (C)2019,Yueyang.
*文件名称:GeoTrans.h
*内容摘要:LiteCV几何变换
*当前版本:V1.0
*作者:杨越
*完成日期:20191020
*/
Mat imrotate(Mat bmpImg,int Angle);
//DIR:0左 1右 2上 3 下
Mat immove(Mat mat,int dir,int distance);
(三)应用举例
这里分别使用这两个函数来实现一下图像的平移和旋转
(1)图像平移测试
/*************************************************
Copyright © Yueyang Co. Ltd. 2019-2029. All rights reserved.
File name: cv.h
Author: Yueyang
Version: V1.0
Description: LiteCV运行主函数
Others:
Log: 11.3 Yueyang
*************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "bmp.h"
#include "cv.h"
#include "GeoTrans.h"
#include "PointOr.h"
#include "BasicGui.h"
int main()
{
Mat src;
Mat_Init();
src=load("..\\picture\\WHU2.bmp");
Mat dst=immove(src,1,90);
save("..\\picture\\test.bmp",&dst);
show(&dst);
destory(&src);
destory(&dst);
return 0;
}
效果:
(2)图片旋转测试
/*************************************************
Copyright © Yueyang Co. Ltd. 2019-2029. All rights reserved.
File name: cv.h
Author: Yueyang
Version: V1.0
Description: LiteCV运行主函数
Others:
Log: 11.3 Yueyang
*************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "bmp.h"
#include "cv.h"
#include "GeoTrans.h"
#include "PointOr.h"
#include "BasicGui.h"
int main()
{
Mat src;
Mat_Init();
src=load("..\\picture\\lena.bmp");
Mat dst=imrotate(src,30);
save("..\\picture\\test.bmp",&dst);
show(&dst);
destory(&src);
destory(&dst);
return 0;
}
效果
(四)写在后面
因为LiteCV项目才刚刚写了一个开头,代码中有错误的地方还望指出。
我已经将项目同步到了github,我会实时更新这个代码仓库。
项目github地址:
LITECV