
图像的几何变换
图片的平移,旋转,缩放,翻转都属于仿射变换!
仿射变换
核心是给出任意三个点,注意不能在一条线上的三个点,然后经过getAffineTransform
函数计算得到仿射变换矩阵,然后再通过warpAffine
函数实现仿射变换
java
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class WarpAffine {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\leaf.png");
//定义原图像中三个点的坐标
Point[] pt1 = new Point[3]; //输入图像点集
pt1[0] = new Point(136, 56);
pt1[1] = new Point(45, 160);
pt1[2] = new Point(215, 150);
//定义目标图像中三个点的坐标
Point[] pt2 = new Point[3]; //输出图像点集
pt2[0] = new Point(50, 80);
pt2[1] = new Point(50, 180);
pt2[2] = new Point(200, 100);
//getAffineTransform()函数用到的数据类型
MatOfPoint2f mop1 = new MatOfPoint2f(pt1);
MatOfPoint2f mop2 = new MatOfPoint2f(pt2);
//计算仿射变换矩阵并进行仿射变换
Mat dst=new Mat();
Mat mat=Imgproc.getAffineTransform(mop1, mop2);
Imgproc.warpAffine(src, dst, mat, src.size());
//在原图像中标记三个点的坐标
Scalar color=new Scalar(255,255,255);
for (int n=0; n<3; n++) {
Imgproc.circle(src, pt1[n], 2, color, 2);
Imgproc.putText(src, n + 1 + "", pt1[n] , 0 , 1, color,3);
}
//在目标图像中标记三个点的坐标
for (int n=0; n<3; n++) {
Imgproc.circle(dst, pt2[n], 2, color, 2);
Imgproc.putText(dst, n + 1 + "", pt2[n] , 0 , 1, color,3);
}
//在屏幕上显示变换前后的图像
HighGui.imshow("src", src);
HighGui.waitKey(0);
HighGui.imshow("warped", dst);
HighGui.waitKey(0);
//在控制台输出仿射变换矩阵
System.out.println(mat.dump());
System.exit(0);
}
}
透视变换
java
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class PerspectiveTransform {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\book.png");
//定义原图像中4个点的坐标
Point[] pt1 = new Point[4];
pt1[0] = new Point(95, 129);
pt1[1] = new Point(260, 157);
pt1[2] = new Point(57, 469);
pt1[3] = new Point(248, 454);
//定义目标图像中4个点的坐标
Point[] pt2 = new Point[4];
pt2[0] = new Point(0, 0);
pt2[1] = new Point(300, 0);
pt2[2] = new Point(0,600);
pt2[3] = new Point(300,600);
//getPerspectiveTransform()函数用到的数据类型
MatOfPoint2f mop1 = new MatOfPoint2f(pt1);
MatOfPoint2f mop2 = new MatOfPoint2f(pt2);
//计算透视变换矩阵并进行仿射变换
Mat dst=new Mat();
Mat matrix=Imgproc.getPerspectiveTransform(mop1, mop2); //获取转换矩阵
Imgproc.warpPerspective(src, dst, matrix, new Size(300,600));
//在屏幕上显示变换前后的图像
HighGui.imshow("src", src);
HighGui.waitKey(0);
HighGui.imshow("dst", dst);
HighGui.waitKey(0);
System.exit(0);
}
}
平移
平移就是将原图的每个像素的坐标都平移x,y的距离,比如下面的就是 向x轴平移30,向y轴平移50
。其中只有30和50是变量
java
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class Translate {
public static void main(String[] args) {
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
//构建用于平移的矩阵
Mat mat = new Mat(2, 3, CvType.CV_64F);
double [] Data=new double[] {1,0,30,0,1,50};
mat.put(0, 0, Data);
//读取图像并在屏幕上显示
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\pond.png");
HighGui.imshow("src", src);
HighGui.waitKey(0);
//进行平移并在屏幕上显示平移后的图像
Mat dst=new Mat();
Imgproc.warpAffine(src, dst, mat, src.size());
HighGui.imshow("translate", dst);
HighGui.waitKey(0);
System.exit(0);
}
}
旋转
以图像为中心,旋转角度为33°,正数表示逆时针
java
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class Rotate {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读入图像并在屏幕上显示
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\fish.png");
HighGui.imshow("src", src);
HighGui.waitKey(0);
//计算旋转用的仿射矩阵
Mat dst=new Mat();
Point center =new Point(src.width()/2.0, src.height()/2.0);
Mat matrix =Imgproc.getRotationMatrix2D(center, 33.0, 1.0);
//旋转图像并在屏幕上显示
Imgproc.warpAffine(src, dst, matrix, src.size(),Imgproc.INTER_LINEAR);
HighGui.imshow("Rotated", dst);
HighGui.waitKey(0);
System.exit(0);
}
}
缩放
java
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class Scale {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读入图像并在屏幕上显示
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\church.png");
HighGui.imshow("src", src);
HighGui.waitKey(0);
//获取原图像尺寸
float width=src.width();
float height=src.height();
//将原图像放大至1.2倍
Mat dst1=new Mat();
float scale1=1.2f; //缩放比例1
Imgproc.resize(src, dst1, new Size(width*scale1,height*scale1));
//将原图像缩小至0.8倍
Mat dst2=new Mat();
float scale2=0.8f; //缩放比例2
Imgproc.resize(src, dst2, new Size(width*scale2,height*scale2));
//在屏幕上显示放大和缩小后的图像
HighGui.imshow("Bigger", dst1);
HighGui.waitKey(0);
HighGui.imshow("Smaller", dst2);
HighGui.waitKey(0);
System.exit(0);
}
}
翻转
java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import java.util.ArrayList;
import java.util.List;
public class Flip {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像文件并在屏幕上显示
Mat src=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\leaf.png");
HighGui.imshow("src", src);
HighGui.waitKey(0);
//绕y轴翻转
Mat f1=new Mat();
Core.flip(src, f1, 1);
//将两幅图像进行水平拼接
List<Mat> mats = new ArrayList<Mat>();
mats.add(src);
mats.add(f1);
Mat d1 = new Mat();
Core.hconcat(mats, d1); //水平拼接
//绕x轴翻转
Mat f2=new Mat();
Core.flip(src, f2, 0);
//绕x,y两个轴翻转
Mat f3=new Mat();
Core.flip(src, f3, -1);
//移除mats中元素
mats.remove(1);
mats.remove(0);
//将x轴翻转图像和两个轴翻转图像进行水平拼接
mats.add(f2);
mats.add(f3);
Mat d2 = new Mat();
Core.hconcat(mats, d2);
//将两幅拼接后的图像垂直再拼接
mats.remove(1);
mats.remove(0);
mats.add(d1);
mats.add(d2);
Mat d3 = new Mat();
Core.vconcat(mats, d3);
//在屏幕上显示最后结果
HighGui.imshow("All", d3);
HighGui.waitKey(0);
System.exit(0);
}
}
图像拼接
hconcat
水平拼接
vconcat
垂直拼接
java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import java.util.ArrayList;
import java.util.List;
public class Concat {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像文件 并克隆
Mat src1=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\church.png");
Mat src2=src1.clone();
//hConcat函数需要的参数类型准备
List<Mat> mat1 = new ArrayList<Mat>();
mat1.add(src1);
mat1.add(src2);
//将2幅图像进行水平拼接
Mat dst = new Mat();
Core.hconcat(mat1, dst);
//在屏幕上显示水平拼接后的图像
HighGui.imshow("hconcat", dst);
HighGui.waitKey(0);
//读取图像文件
Mat src3=Imgcodecs.imread("C:\\Users\\Think\\Desktop\\TestCV\\leaf.png");
Mat src4=src3.clone();
//vConcat函数需要的参数类型准备
List<Mat> mat2 = new ArrayList<Mat>();
mat2.add(src3);
mat2.add(src4);
//将2幅图像进行垂直拼接
Mat dst2 = new Mat();
Core.vconcat(mat2, dst2);
//在屏幕上显示垂直拼接后的图像
HighGui.imshow("vconcat", dst2);
HighGui.waitKey(0);
System.exit(0);
}
}