Test for image enhancement
This commit is contained in:
parent
32d8f2e5fb
commit
c7f9482883
@ -5,6 +5,7 @@ import com.zhangy.skyeye.common.extend.anno.IgnoreAuth;
|
|||||||
import com.zhangy.skyeye.common.extend.enums.EnumUtil;
|
import com.zhangy.skyeye.common.extend.enums.EnumUtil;
|
||||||
import com.zhangy.skyeye.common.extend.exception.ServiceException;
|
import com.zhangy.skyeye.common.extend.exception.ServiceException;
|
||||||
import com.zhangy.skyeye.common.extend.util.DateUtil;
|
import com.zhangy.skyeye.common.extend.util.DateUtil;
|
||||||
|
import com.zhangy.skyeye.common.extend.util.ObjectUtil;
|
||||||
import com.zhangy.skyeye.common.pojo.result.Result;
|
import com.zhangy.skyeye.common.pojo.result.Result;
|
||||||
import com.zhangy.skyeye.jm.consts.JmJobModeEnum;
|
import com.zhangy.skyeye.jm.consts.JmJobModeEnum;
|
||||||
import com.zhangy.skyeye.jm.dto.JmJobDTO;
|
import com.zhangy.skyeye.jm.dto.JmJobDTO;
|
||||||
@ -77,6 +78,10 @@ public class JmJobController {
|
|||||||
@PostMapping("/save")
|
@PostMapping("/save")
|
||||||
public Object insert(@Valid @RequestBody JmJobDTO e) {
|
public Object insert(@Valid @RequestBody JmJobDTO e) {
|
||||||
JmJobModeEnum mode = EnumUtil.parseEx(JmJobModeEnum.class, e.getMode());
|
JmJobModeEnum mode = EnumUtil.parseEx(JmJobModeEnum.class, e.getMode());
|
||||||
|
if (mode != JmJobModeEnum.CRUISE && ObjectUtil.isEmpty(e.getPointList())) {
|
||||||
|
throw ServiceException.noLog("任务点不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
clearId(e);
|
clearId(e);
|
||||||
// 默认执行一次性任务
|
// 默认执行一次性任务
|
||||||
if (e.getType() == null) {
|
if (e.getType() == null) {
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public class ImageUtil {
|
|||||||
int lightRate = rotateDTO.getLightRate();
|
int lightRate = rotateDTO.getLightRate();
|
||||||
if (lightRate != 0) {
|
if (lightRate != 0) {
|
||||||
//OpenCVUtil.multiply(image, lightRate);
|
//OpenCVUtil.multiply(image, lightRate);
|
||||||
OpenCVUtil.enhanceContrast(image, lightRate, 0);
|
// OpenCVUtil.enhanceContrast(image, lightRate, 0);
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,15 +211,17 @@ public class SarImageServiceImpl implements ISarImageService {
|
|||||||
redisUtil.hset("jmImgJoin-" + airlineExecId, CACHE_FIELD_CURR_FRAME_NO, frameNo, CACHE_EXPIRE_SECOND);// 更新帧号
|
redisUtil.hset("jmImgJoin-" + airlineExecId, CACHE_FIELD_CURR_FRAME_NO, frameNo, CACHE_EXPIRE_SECOND);// 更新帧号
|
||||||
// ### 亮度调整,用于可靠udp版本图像,固定使用系数0.5
|
// ### 亮度调整,用于可靠udp版本图像,固定使用系数0.5
|
||||||
// 拆分多张图片,去掉自适应调整
|
// 拆分多张图片,去掉自适应调整
|
||||||
if (IMG_MAX_WITH > 20000) {
|
// if (IMG_MAX_WITH > 20000) {
|
||||||
SarImageToneAdjuster.autoToneWithClipping(baseMat, 0.5f);
|
SarImageToneAdjuster.autoToneWithClipping(baseMat, 0.5f);
|
||||||
|
// Mat enhancedImage = SarImageToneAdjuster.enhanceSarImage(baseMat);
|
||||||
// RadarDisplayOptions options = new RadarDisplayOptions();
|
// RadarDisplayOptions options = new RadarDisplayOptions();
|
||||||
// SarImageToneAdjuster.processForDisplayMat(baseMat, options);
|
// SarImageToneAdjuster.processForDisplayMat(baseMat, options);
|
||||||
// SarImageToneAdjuster.applyPseudoColorMat(baseMat, options);
|
// SarImageToneAdjuster.applyPseudoColorMat(baseMat, options);
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 5.保存后处理图(异步),用于前端显示
|
// 5.保存后处理图(异步),用于前端显示
|
||||||
generateAfterMat(currAirline, baseMat, currPath, uav.getSarImageLight());
|
generateAfterMat(currAirline, baseMat, currPath, uav.getSarImageLight());
|
||||||
|
// generateAfterMat(currAirline, enhancedImage, currPath, uav.getSarImageLight());
|
||||||
|
|
||||||
// 6.更新基准图坐标和帧号
|
// 6.更新基准图坐标和帧号
|
||||||
JmImage imageInfo = saveImage(uav, airlineExecId, base, imagePath, imageFrame, frameNo, lostImage);
|
JmImage imageInfo = saveImage(uav, airlineExecId, base, imagePath, imageFrame, frameNo, lostImage);
|
||||||
@ -275,15 +277,15 @@ public class SarImageServiceImpl implements ISarImageService {
|
|||||||
private Mat generateBaseMat(JmImage base, Mat currImage, int currNo, float currMax, String imagePath, Integer baseNo) {
|
private Mat generateBaseMat(JmImage base, Mat currImage, int currNo, float currMax, String imagePath, Integer baseNo) {
|
||||||
Mat baseImage = OpenCVUtil.read(imagePath); // 从硬盘加载基准图
|
Mat baseImage = OpenCVUtil.read(imagePath); // 从硬盘加载基准图
|
||||||
// 归一化调整
|
// 归一化调整
|
||||||
if (base.getId() != null) {
|
// if (base.getId() != null) {
|
||||||
float baseMax = base.getMax();
|
// float baseMax = base.getMax();
|
||||||
//System.out.println("基准图:" + baseMax + ",当前图:" + currMax);
|
// //System.out.println("基准图:" + baseMax + ",当前图:" + currMax);
|
||||||
if (baseMax < currMax) {
|
// if (baseMax < currMax) {
|
||||||
OpenCVUtil.multiply(baseImage, baseMax / currMax);
|
// OpenCVUtil.multiply(baseImage, baseMax / currMax);
|
||||||
} else if (baseMax > currMax) {
|
// } else if (baseMax > currMax) {
|
||||||
OpenCVUtil.multiply(currImage , currMax / baseMax);
|
// OpenCVUtil.multiply(currImage , currMax / baseMax);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Mat baseMat = ImageUtil.join(baseImage, baseNo, currImage, currNo); // 会释放 currImage baseImage 资源
|
Mat baseMat = ImageUtil.join(baseImage, baseNo, currImage, currNo); // 会释放 currImage baseImage 资源
|
||||||
if (baseMat != null) { // 若拼接成功则回写硬盘,拼接失败按丢图处理,不改动基准图
|
if (baseMat != null) { // 若拼接成功则回写硬盘,拼接失败按丢图处理,不改动基准图
|
||||||
OpenCVUtil.write(imagePath, baseMat, false);
|
OpenCVUtil.write(imagePath, baseMat, false);
|
||||||
|
|||||||
@ -2,11 +2,14 @@ package com.zhangy.skyeye.sar.util;
|
|||||||
|
|
||||||
import org.opencv.core.*;
|
import org.opencv.core.*;
|
||||||
import org.opencv.imgcodecs.Imgcodecs;
|
import org.opencv.imgcodecs.Imgcodecs;
|
||||||
|
import org.opencv.imgproc.CLAHE;
|
||||||
import org.opencv.imgproc.Imgproc;
|
import org.opencv.imgproc.Imgproc;
|
||||||
|
|
||||||
import org.opencv.core.Core;
|
import org.opencv.core.Core;
|
||||||
import org.opencv.core.CvType;
|
import org.opencv.core.CvType;
|
||||||
import org.opencv.core.Mat;
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.photo.Photo;
|
||||||
|
import org.opencv.photo.Tonemap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -643,4 +646,116 @@ public class SarImageToneAdjuster {
|
|||||||
|
|
||||||
image.put(0, 0, data);
|
image.put(0, 0, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reinhard 局部色调映射
|
||||||
|
*/
|
||||||
|
public static Mat reinhardToneMapping(Mat src,
|
||||||
|
float gamma,
|
||||||
|
float intensity,
|
||||||
|
float lightAdapt,
|
||||||
|
float colorAdapt) {
|
||||||
|
|
||||||
|
Mat srcFloat = new Mat();
|
||||||
|
src.convertTo(srcFloat, CvType.CV_32FC3, 1.0 / 255.0);
|
||||||
|
|
||||||
|
// 注意这里的类型
|
||||||
|
Tonemap tonemap = Photo.createTonemapReinhard(
|
||||||
|
gamma,
|
||||||
|
intensity,
|
||||||
|
lightAdapt,
|
||||||
|
colorAdapt
|
||||||
|
);
|
||||||
|
|
||||||
|
Mat dstFloat = new Mat();
|
||||||
|
tonemap.process(srcFloat, dstFloat);
|
||||||
|
|
||||||
|
Mat dst = new Mat();
|
||||||
|
dstFloat.convertTo(dst, CvType.CV_8UC3, 255.0);
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对输入图像做 CLAHE (在 LAB 空间)
|
||||||
|
*/
|
||||||
|
public static Mat applyCLAHEGray(Mat src,
|
||||||
|
double clipLimit,
|
||||||
|
Size tileGridSize) {
|
||||||
|
|
||||||
|
CLAHE clahe = Imgproc.createCLAHE();
|
||||||
|
clahe.setClipLimit(clipLimit);
|
||||||
|
clahe.setTilesGridSize(tileGridSize);
|
||||||
|
|
||||||
|
Mat dst = new Mat();
|
||||||
|
clahe.apply(src, dst);
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat enhanceSarImage(Mat src) {
|
||||||
|
|
||||||
|
if (src.channels() != 1) {
|
||||||
|
throw new IllegalArgumentException("Only single channel supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
Mat floatMat = new Mat();
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// 转 float
|
||||||
|
// =========================
|
||||||
|
if (src.type() == CvType.CV_16U) {
|
||||||
|
src.convertTo(floatMat, CvType.CV_32F, 1.0 / 65535.0);
|
||||||
|
} else if (src.type() == CvType.CV_8U) {
|
||||||
|
src.convertTo(floatMat, CvType.CV_32F, 1.0 / 255.0);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// log 压缩
|
||||||
|
// =========================
|
||||||
|
Core.add(floatMat, Scalar.all(1e-6), floatMat);
|
||||||
|
Core.log(floatMat, floatMat);
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// 固定裁剪
|
||||||
|
// =========================
|
||||||
|
double low = -8; // 根据你的数据调
|
||||||
|
double high = 0;
|
||||||
|
|
||||||
|
Core.min(floatMat, new Scalar(high), floatMat);
|
||||||
|
Core.max(floatMat, new Scalar(low), floatMat);
|
||||||
|
|
||||||
|
Core.subtract(floatMat, new Scalar(low), floatMat);
|
||||||
|
Core.divide(floatMat, new Scalar(high - low), floatMat);
|
||||||
|
// Core.normalize(floatMat, floatMat, 0.0, 1.0, Core.NORM_MINMAX);
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// 转 8bit
|
||||||
|
// =========================
|
||||||
|
Mat img8 = new Mat();
|
||||||
|
floatMat.convertTo(img8, CvType.CV_8U, 255.0);
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// CLAHE
|
||||||
|
// =========================
|
||||||
|
CLAHE clahe = Imgproc.createCLAHE();
|
||||||
|
clahe.setClipLimit(3.0);
|
||||||
|
clahe.setTilesGridSize(new Size(8, 8));
|
||||||
|
|
||||||
|
Mat claheOut = new Mat();
|
||||||
|
clahe.apply(img8, claheOut);
|
||||||
|
|
||||||
|
// =========================
|
||||||
|
// Unsharp Mask
|
||||||
|
// =========================
|
||||||
|
Mat blur = new Mat();
|
||||||
|
Imgproc.GaussianBlur(claheOut, blur, new Size(0,0), 1.0);
|
||||||
|
|
||||||
|
Mat sharpened = new Mat();
|
||||||
|
Core.addWeighted(claheOut, 1.3, blur, -0.3, 0, sharpened);
|
||||||
|
|
||||||
|
return sharpened;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user