版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
package com.zxj.opencv.demo;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
/**
* 2.医学图像处理
*
* @author zxj
*
*/
public class MedicineImageProcess {
private static final String DIR = "d:/opencv/";
private static final String TEST_IMG = "d:/11.jpg";
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);// 加载opencv c++动态库
equalizeHist();
convertTo();
filter2D();
matchTemplate();
warpAffine();
// remap();
threshold();
adaptiveThreshold();
compare();
}
/******** 2.2.1 增强 *******/
public static void equalizeHist() {// 直方图均衡化
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_GRAYSCALE);// 以单通道读取
Mat dst = new Mat();
Imgproc.equalizeHist(src, dst);
Imgcodecs.imwrite(DIR + "equalizeHist.jpg", dst);// 写入文件
}
public static void convertTo() {// 亮度和对比度
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
// alpha取图片默认,亮度设为50,可以改动这个值来调节效果
src.convertTo(dst, 50);
Imgcodecs.imwrite(DIR + "convertTo.jpg", dst);// 写入文件
}
/******** 2.2.2 卷积 *******/
public static void filter2D() {// filter2D计算
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
Imgproc.filter2D(src, dst, src.depth(), Mat.zeros(3, 3, CvType.CV_8UC1), new Point(-1, -1), 50,
Core.BORDER_CONSTANT);
Imgcodecs.imwrite(DIR + "filter2D.jpg", dst);// 写入文件
}
/******** 2.2.3 模版匹配 *******/
public static void matchTemplate() {// 模版匹配
Mat src = Imgcodecs.imread("d:/src1.jpg", Imgcodecs.IMREAD_COLOR);
Mat templ = Imgcodecs.imread("d:/src2.jpg", Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
dst.create(src.rows() - templ.rows() + 1, src.cols() - templ.cols() + 1, CvType.CV_32FC1);
// matchMethod TM_SQDIFF、TM_CCOEFF_NORMED
int matchMethod = Imgproc.TM_CCOEFF_NORMED;
Imgproc.matchTemplate(src, templ, dst, matchMethod);
Core.normalize(dst, dst, 0, 1, Core.NORM_MINMAX, -1, new Mat());
MinMaxLocResult maxLocResult = Core.minMaxLoc(dst);
Point matchLoc;
if (matchMethod == Imgproc.TM_SQDIFF || matchMethod == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = maxLocResult.minLoc;
} else {
matchLoc = maxLocResult.maxLoc;
}
// 绘制矩形圈出匹配区域
Imgproc.rectangle(src, matchLoc, new Point(matchLoc.x + templ.cols(), matchLoc.y + templ.rows()),
new Scalar(0, 0, 255), 2, 8, 0);
Imgcodecs.imwrite(DIR + "matchTemplate.jpg", src);// 写入文件
}
/******** 2.2.4 仿射变换&同1.2.5旋转 *******/
public static void warpAffine() {// 仿射变换
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
Point center = new Point(src.cols() / 2, src.rows() / 2);// 原图中心点
double angle = 50;// 旋转角度
double scale = 1;// 缩放比例
Mat rot_mat = Imgproc.getRotationMatrix2D(center, angle, scale);
Imgproc.warpAffine(src, dst, rot_mat, src.size(), Imgproc.INTER_LINEAR, Core.BORDER_DEFAULT, Scalar.all(0));//
Imgcodecs.imwrite(DIR + "warpAffine.jpg", dst);// 写入文件
}
/******** 2.2.5 重映射 *******/
public static void remap() {// 重映射
Mat src = Imgcodecs.imread("d:/26e813228fca8bca2434f1877067dc245965d7e6f1b3e.png", Imgcodecs.IMREAD_COLOR);
Mat map_x = new Mat(src.size(), CvType.CV_32FC1);
Mat map_y = new Mat(src.size(), CvType.CV_32FC1);
Mat dst = new Mat();
// 复制
for (int i = 0; i < src.rows(); i++) {
for (int j = 0; j < src.cols(); i++) {
map_x.put(i, j, j);
map_y.put(i, j, i);
}
}
Imgproc.remap(src, dst, map_x, map_y, Imgproc.INTER_LINEAR, Core.BORDER_DEFAULT, new Scalar(0, 0, 0));
// Mat kernel=Imgproc.getGaussianKernel(5, 2,CvType.CV_32F);
Imgcodecs.imwrite(DIR + "copy.jpg", dst);// 写入文件
}
/******** 2.2.6 分割 *******/
public static void threshold() {// 基本阈值分割
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
Imgproc.threshold(src, dst, 128, 255, Imgproc.THRESH_BINARY);// type=THRESH_BINARY和THRESH_BINARY_INV maxval需要设定
Imgcodecs.imwrite(DIR + "threshold.jpg", dst);// 写入文件
}
public static void adaptiveThreshold() {// 自适应阈值分割
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_GRAYSCALE);// 8位单通道
Mat dst = new Mat();
Imgproc.adaptiveThreshold(src, dst, 128, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 3, 1);// type只能为THRESH_BINARY或THRESH_BINARY_INV
Imgcodecs.imwrite(DIR + "adaptiveThreshold.jpg", dst);// 写入文件
}
public static void compare() {// compare函数
Mat src = Imgcodecs.imread(TEST_IMG, Imgcodecs.IMREAD_COLOR);
Mat src2 = Imgcodecs.imread("d:/31.jpg", Imgcodecs.IMREAD_COLOR);
Mat dst = new Mat();
int cmpop = Core.CMP_GE;
if (src.size().area() > src.size().area()) {
cmpop = Core.CMP_GT;
} else if (src.size().area() == src.size().area()) {
cmpop = Core.CMP_EQ;
} else {
cmpop = Core.CMP_LT;
}
Core.compare(src, src2, dst, cmpop);
Imgcodecs.imwrite(DIR + "compare.jpg", dst);// 写入文件
}
}