├── .gitignore ├── .idea ├── compiler.xml ├── encodings.xml ├── libraries │ └── Maven__junit_junit_3_8_1.xml ├── modules.xml └── vcs.xml ├── ImageEnhanceViaFusion.iml ├── LICENSE ├── Matlab Codes.zip ├── README-images ├── enh-1.png ├── enh-2.png ├── enh-3.png ├── enh-4.png ├── enh-5.png ├── enh-6.png ├── enh-8.png ├── enh-9.png ├── org-1.jpg ├── org-2.png ├── org-3.png ├── org-4.png ├── org-5.png ├── org-6.png ├── org-8.png ├── org-9.png ├── w1-2.png ├── w1-3.png ├── w1-4.png ├── w1-5.png ├── w1-6.png ├── w1-8.png ├── w1-9.png ├── w2-2.png ├── w2-3.png ├── w2-4.png ├── w2-5.png ├── w2-6.png ├── w2-8.png └── w2-9.png ├── README.md ├── images ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5-2.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg └── 9.jpg ├── libopencv_java320.dylib ├── paper.pdf ├── pom.xml ├── src └── main │ └── java │ └── com │ └── isaac │ ├── enhance │ ├── EnhanceFunc.java │ ├── Pyramid.java │ └── WeightCalculate.java │ └── utils │ ├── ColorBalance.java │ ├── Filters.java │ └── ImShow.java └── target ├── classes └── META-INF │ ├── MANIFEST.MF │ └── maven │ └── com.isaac.enhance │ └── ImageEnhanceViaFusion │ ├── pom.properties │ └── pom.xml ├── maven-archiver └── pom.properties └── maven-status └── maven-compiler-plugin └── compile └── default-compile ├── createdFiles.lst └── inputFiles.lst /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__junit_junit_3_8_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ImageEnhanceViaFusion.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ZHANG HAO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Matlab Codes.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/Matlab Codes.zip -------------------------------------------------------------------------------- /README-images/enh-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-1.png -------------------------------------------------------------------------------- /README-images/enh-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-2.png -------------------------------------------------------------------------------- /README-images/enh-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-3.png -------------------------------------------------------------------------------- /README-images/enh-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-4.png -------------------------------------------------------------------------------- /README-images/enh-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-5.png -------------------------------------------------------------------------------- /README-images/enh-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-6.png -------------------------------------------------------------------------------- /README-images/enh-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-8.png -------------------------------------------------------------------------------- /README-images/enh-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/enh-9.png -------------------------------------------------------------------------------- /README-images/org-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-1.jpg -------------------------------------------------------------------------------- /README-images/org-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-2.png -------------------------------------------------------------------------------- /README-images/org-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-3.png -------------------------------------------------------------------------------- /README-images/org-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-4.png -------------------------------------------------------------------------------- /README-images/org-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-5.png -------------------------------------------------------------------------------- /README-images/org-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-6.png -------------------------------------------------------------------------------- /README-images/org-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-8.png -------------------------------------------------------------------------------- /README-images/org-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/org-9.png -------------------------------------------------------------------------------- /README-images/w1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-2.png -------------------------------------------------------------------------------- /README-images/w1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-3.png -------------------------------------------------------------------------------- /README-images/w1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-4.png -------------------------------------------------------------------------------- /README-images/w1-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-5.png -------------------------------------------------------------------------------- /README-images/w1-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-6.png -------------------------------------------------------------------------------- /README-images/w1-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-8.png -------------------------------------------------------------------------------- /README-images/w1-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w1-9.png -------------------------------------------------------------------------------- /README-images/w2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-2.png -------------------------------------------------------------------------------- /README-images/w2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-3.png -------------------------------------------------------------------------------- /README-images/w2-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-4.png -------------------------------------------------------------------------------- /README-images/w2-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-5.png -------------------------------------------------------------------------------- /README-images/w2-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-6.png -------------------------------------------------------------------------------- /README-images/w2-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-8.png -------------------------------------------------------------------------------- /README-images/w2-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/README-images/w2-9.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Underwater Image Enhance via Fusion 2 | 3 | ![Authour](https://img.shields.io/badge/Author-Zhang%20Hao%20(Isaac%20Changhau)-blue.svg) ![](https://img.shields.io/badge/Java-1.8-brightgreen.svg) ![](https://img.shields.io/badge/OpenCV-3.2.0-brightgreen.svg) 4 | 5 | **Notice**: _All the codes are integrated in my newly created repository: [OptimizedImageEnhance](https://github.com/IsaacChanghau/OptimizedImageEnhance), this repository will be deleted later, and the compressed file of this repository is also available in the new repository: [[link]](https://github.com/IsaacChanghau/OptimizedImageEnhance/blob/master/pre_standalones/ImageEnhanceViaFusion-master.zip)._ 6 | 7 | It is a Java implementation of algorithms proposed in the [paper](http://perso.telecom-paristech.fr/~Gousseau/ProjAnim/2015/ImageSousMarine.pdf): Enhancing Underwater Images and Videos by Fusion, published by Cosmin Ancuti on [CVPR](https://en.wikipedia.org/wiki/Conference_on_Computer_Vision_and_Pattern_Recognition), 2012. 8 | 9 | This paper describes a novel strategy to enhance underwater videos and images. Built on the fusion principles, the strategy derives the inputs and the weight measures only from the degraded version of the image. In order to overcome the limitations of the underwater medium, two inputs are defined that represent color corrected and contrast enhanced versions of the original underwater image/frame, but also four weight maps that aim to increase the visibility of the distant objects degraded due to the medium scattering and absorption. The strategy is a single image approach that does not require specialized hardware or knowledge about the underwater conditions or scene structure. The fusion framework also supports temporal coherence between adjacent frames by performing an effective edge preserving noise reduction strategy. The enhanced images and videos are characterized by reduced noise level, better exposedness of the dark regions, improved global contrast while the finest details and edges are enhanced significantly. 10 | 11 | **NOTE**: The image showing method is obtain from the repository: [ImShow-Java-OpenCV](https://github.com/master-atul/ImShow-Java-OpenCV). And the implementation of Matlab are put in this project too. 12 | 13 | 14 | ### Requirements 15 | 16 | * [Java 1.8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). 17 | 18 | * [OpenCV](http://opencv.org/). To make the OpenCV can work with JAVA IDE like IntelliJ or Eclipse, you may need to follow the guidance of [OpenCV Java Tutorials](http://opencv-java-tutorials.readthedocs.io/en/latest/01-installing-opencv-for-java.html) to set up OpenCV for Java in your favorite IDE. 19 | 20 | ### Results 21 | 22 | ##### Heavy Distorted Fish Example 23 | 24 | 25 | ##### Enhancement Examples with Normalized Weight Maps 26 | 27 | 28 | 29 | 30 | 31 | 32 | #### Other Results 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/3.jpg -------------------------------------------------------------------------------- /images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/4.jpg -------------------------------------------------------------------------------- /images/5-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/5-2.jpg -------------------------------------------------------------------------------- /images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/5.jpg -------------------------------------------------------------------------------- /images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/6.jpg -------------------------------------------------------------------------------- /images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/7.jpg -------------------------------------------------------------------------------- /images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/8.jpg -------------------------------------------------------------------------------- /images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/images/9.jpg -------------------------------------------------------------------------------- /libopencv_java320.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/libopencv_java320.dylib -------------------------------------------------------------------------------- /paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/paper.pdf -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.isaac.enhance 6 | ImageEnhanceViaFusion 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | ImageEnhanceViaFusion 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | 27 | ImageEnhanceViaFusion 28 | 29 | 30 | org.apache.maven.plugins 31 | maven-compiler-plugin 32 | 33 | 1.8 34 | 1.8 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-shade-plugin 40 | 2.3 41 | 42 | 43 | package 44 | 45 | shade 46 | 47 | 48 | 49 | 50 | com.isaac.enhance.EnhanceFunc 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/enhance/EnhanceFunc.java: -------------------------------------------------------------------------------- 1 | package com.isaac.enhance; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | import org.opencv.core.Core; 8 | import org.opencv.core.CvType; 9 | import org.opencv.core.Mat; 10 | import org.opencv.core.Scalar; 11 | import org.opencv.imgcodecs.Imgcodecs; 12 | import org.opencv.imgproc.CLAHE; 13 | import org.opencv.imgproc.Imgproc; 14 | 15 | import com.isaac.utils.ColorBalance; 16 | import com.isaac.utils.ImShow; 17 | 18 | public class EnhanceFunc { 19 | 20 | static { 21 | System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 22 | } 23 | 24 | public static void main(String[] args) { 25 | String imgPath = "images/5.jpg"; 26 | Mat image = Imgcodecs.imread(imgPath, Imgcodecs.CV_LOAD_IMAGE_COLOR); 27 | new ImShow("original").showImage(image); 28 | // color balance 29 | Mat img1 = ColorBalance.SimplestColorBalance(image, 5); 30 | img1.convertTo(img1, CvType.CV_8UC1); 31 | // Perform sRGB to CIE Lab color space conversion 32 | Mat LabIm1 = new Mat(); 33 | Imgproc.cvtColor(img1, LabIm1, Imgproc.COLOR_BGR2Lab); 34 | Mat L1 = new Mat(); 35 | Core.extractChannel(LabIm1, L1, 0); 36 | // apply CLAHE 37 | Mat[] result = applyCLAHE(LabIm1, L1); 38 | Mat img2 = result[0]; 39 | Mat L2 = result[1]; 40 | // calculate normalized weight 41 | Mat w1 = calWeight(img1, L1); 42 | Mat w2 = calWeight(img2, L2); 43 | Mat sumW = new Mat(); 44 | Core.add(w1, w2, sumW); 45 | Core.divide(w1, sumW, w1); 46 | Core.divide(w2, sumW, w2); 47 | // construct the gaussian pyramid for weight 48 | int level = 5; 49 | Mat[] weight1 = Pyramid.GaussianPyramid(w1, level); 50 | Mat[] weight2 = Pyramid.GaussianPyramid(w2, level); 51 | // construct the laplacian pyramid for input image channel 52 | img1.convertTo(img1, CvType.CV_32F); 53 | img2.convertTo(img2, CvType.CV_32F); 54 | List bgr = new ArrayList(); 55 | Core.split(img1, bgr); 56 | Mat[] bCnl1 = Pyramid.LaplacianPyramid(bgr.get(0), level); 57 | Mat[] gCnl1 = Pyramid.LaplacianPyramid(bgr.get(1), level); 58 | Mat[] rCnl1 = Pyramid.LaplacianPyramid(bgr.get(2), level); 59 | bgr.clear(); 60 | Core.split(img2, bgr); 61 | Mat[] bCnl2 = Pyramid.LaplacianPyramid(bgr.get(0), level); 62 | Mat[] gCnl2 = Pyramid.LaplacianPyramid(bgr.get(1), level); 63 | Mat[] rCnl2 = Pyramid.LaplacianPyramid(bgr.get(2), level); 64 | // fusion process 65 | Mat[] bCnl = new Mat[level]; 66 | Mat[] gCnl = new Mat[level]; 67 | Mat[] rCnl = new Mat[level]; 68 | for (int i = 0; i < level; i++) { 69 | Mat cn = new Mat(); 70 | Core.add(bCnl1[i].mul(weight1[i]), bCnl2[i].mul(weight2[i]), cn); 71 | bCnl[i] = cn.clone(); 72 | Core.add(gCnl1[i].mul(weight1[i]), gCnl2[i].mul(weight2[i]), cn); 73 | gCnl[i] = cn.clone(); 74 | Core.add(rCnl1[i].mul(weight1[i]), rCnl2[i].mul(weight2[i]), cn); 75 | rCnl[i] = cn.clone(); 76 | } 77 | // reconstruct & output 78 | Mat bChannel = Pyramid.PyramidReconstruct(bCnl); 79 | Mat gChannel = Pyramid.PyramidReconstruct(gCnl); 80 | Mat rChannel = Pyramid.PyramidReconstruct(rCnl); 81 | Mat fusion = new Mat(); 82 | Core.merge(new ArrayList(Arrays.asList(bChannel, gChannel, rChannel)), fusion); 83 | fusion.convertTo(fusion, CvType.CV_8UC1); 84 | new ImShow("fusion").showImage(fusion); 85 | } 86 | 87 | private static Mat[] applyCLAHE(Mat img, Mat L) { 88 | Mat[] result = new Mat[2]; 89 | CLAHE clahe = Imgproc.createCLAHE(); 90 | clahe.setClipLimit(2.0); 91 | Mat L2 = new Mat(); 92 | clahe.apply(L, L2); 93 | Mat LabIm2 = new Mat(); 94 | List lab = new ArrayList(); 95 | Core.split(img, lab); 96 | Core.merge(new ArrayList(Arrays.asList(L2, lab.get(1), lab.get(2))), LabIm2); 97 | Mat img2 = new Mat(); 98 | Imgproc.cvtColor(LabIm2, img2, Imgproc.COLOR_Lab2BGR); 99 | result[0] = img2; 100 | result[1] = L2; 101 | return result; 102 | } 103 | 104 | private static Mat calWeight(Mat img, Mat L) { 105 | Core.divide(L, new Scalar(255.0), L); 106 | L.convertTo(L, CvType.CV_32F); 107 | // calculate laplacian contrast weight 108 | Mat WL = WeightCalculate.LaplacianContrast(L); 109 | WL.convertTo(WL, L.type()); 110 | // calculate Local contrast weight 111 | Mat WC = WeightCalculate.LocalContrast(L); 112 | WC.convertTo(WC, L.type()); 113 | // calculate the saliency weight 114 | Mat WS = WeightCalculate.Saliency(img); 115 | WS.convertTo(WS, L.type()); 116 | // calculate the exposedness weight 117 | Mat WE = WeightCalculate.Exposedness(L); 118 | WE.convertTo(WE, L.type()); 119 | // sum 120 | Mat weight = WL.clone(); 121 | Core.add(weight, WC, weight); 122 | Core.add(weight, WS, weight); 123 | Core.add(weight, WE, weight); 124 | return weight; 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/enhance/Pyramid.java: -------------------------------------------------------------------------------- 1 | package com.isaac.enhance; 2 | 3 | import org.opencv.core.Core; 4 | import org.opencv.core.Mat; 5 | import org.opencv.core.Size; 6 | import org.opencv.imgproc.Imgproc; 7 | 8 | public class Pyramid { 9 | 10 | public static Mat[] GaussianPyramid(Mat img, int level) { 11 | Mat[] gaussPyr = new Mat[level]; 12 | Mat mask = filterMask(img); 13 | Mat tmp = new Mat(); 14 | Imgproc.filter2D(img, tmp, -1, mask); 15 | gaussPyr[0] = tmp.clone(); 16 | Mat tmpImg = img.clone(); 17 | for (int i = 1; i < level; i++) { 18 | // resize image 19 | Imgproc.resize(tmpImg, tmpImg, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR); 20 | // blur image 21 | tmp = new Mat(); 22 | Imgproc.filter2D(tmpImg, tmp, -1, mask); 23 | gaussPyr[i] = tmp.clone(); 24 | } 25 | return gaussPyr; 26 | } 27 | 28 | public static Mat[] LaplacianPyramid(Mat img, int level) { 29 | Mat[] lapPyr = new Mat[level]; 30 | //Mat mask = filterMask(img); 31 | lapPyr[0] = img.clone(); 32 | Mat tmpImg = img.clone(); 33 | for (int i = 1; i < level; i++) { 34 | // resize image 35 | Imgproc.resize(tmpImg, tmpImg, new Size(), 0.5, 0.5, Imgproc.INTER_LINEAR); 36 | lapPyr[i] = tmpImg.clone(); 37 | } 38 | // calculate the DoG 39 | for (int i = 0; i < level - 1; i++) { 40 | Mat tmpPyr = new Mat(); 41 | Imgproc.resize(lapPyr[i + 1], tmpPyr, lapPyr[i].size(), 0, 0, Imgproc.INTER_LINEAR); 42 | Core.subtract(lapPyr[i], tmpPyr, lapPyr[i]); 43 | } 44 | return lapPyr; 45 | } 46 | 47 | public static Mat PyramidReconstruct(Mat[] pyramid) { 48 | int level = pyramid.length; 49 | for (int i = level - 1; i > 0; i--) { 50 | Mat tmpPyr = new Mat(); 51 | Imgproc.resize(pyramid[i], tmpPyr, pyramid[i - 1].size(), 0, 0, Imgproc.INTER_LINEAR); 52 | Core.add(pyramid[i - 1], tmpPyr, pyramid[i - 1]); 53 | } 54 | return pyramid[0]; 55 | } 56 | 57 | private static Mat filterMask(Mat img) { 58 | double[] h = { 1.0 / 16.0, 4.0 / 16.0, 6.0 / 16.0, 4.0 / 16.0, 1.0 / 16.0 }; 59 | Mat mask = new Mat(h.length, h.length, img.type()); 60 | for (int i = 0; i < h.length; i++) { 61 | for (int j = 0; j < h.length; j++) { 62 | mask.put(i, j, h[i] * h[j]); 63 | } 64 | } 65 | return mask; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/enhance/WeightCalculate.java: -------------------------------------------------------------------------------- 1 | package com.isaac.enhance; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.opencv.core.Core; 7 | import org.opencv.core.CvType; 8 | import org.opencv.core.Mat; 9 | import org.opencv.core.Scalar; 10 | import org.opencv.core.Size; 11 | import org.opencv.imgproc.Imgproc; 12 | 13 | public class WeightCalculate { 14 | 15 | public static Mat Saliency(Mat img) { 16 | // blur image with a 3x3 or 5x5 Gaussian filter 17 | Mat gfbgr = new Mat(); 18 | Imgproc.GaussianBlur(img, gfbgr, new Size(3, 3), 3); 19 | // Perform sRGB to CIE Lab color space conversion 20 | Mat LabIm = new Mat(); 21 | Imgproc.cvtColor(gfbgr, LabIm, Imgproc.COLOR_BGR2Lab); 22 | // Compute Lab average values (note that in the paper this average is found from the 23 | // un-blurred original image, but the results are quite similar) 24 | List lab = new ArrayList(); 25 | Core.split(LabIm, lab); 26 | Mat l = lab.get(0); 27 | l.convertTo(l, CvType.CV_32F); 28 | Mat a = lab.get(1); 29 | a.convertTo(a, CvType.CV_32F); 30 | Mat b = lab.get(2); 31 | b.convertTo(b, CvType.CV_32F); 32 | double lm = Core.mean(l).val[0]; 33 | double am = Core.mean(a).val[0]; 34 | double bm = Core.mean(b).val[0]; 35 | // Finally compute the saliency map 36 | Mat sm = Mat.zeros(l.rows(), l.cols(), l.type()); 37 | Core.subtract(l, new Scalar(lm), l); 38 | Core.subtract(a, new Scalar(am), a); 39 | Core.subtract(b, new Scalar(bm), b); 40 | Core.add(sm, l.mul(l), sm); 41 | Core.add(sm, a.mul(a), sm); 42 | Core.add(sm, b.mul(b), sm); 43 | return sm; 44 | } 45 | 46 | public static Mat LaplacianContrast(Mat img) { 47 | Mat laplacian = new Mat(); 48 | Imgproc.Laplacian(img, laplacian, img.depth()); 49 | //Imgproc.Laplacian(img, laplacian, img.depth(), 3, 1, 0); 50 | Core.convertScaleAbs(laplacian, laplacian); 51 | return laplacian; 52 | } 53 | 54 | public static Mat LocalContrast(Mat img) { 55 | double[] h = { 1.0 / 16.0, 4.0 / 16.0, 6.0 / 16.0, 4.0 / 16.0, 1.0 / 16.0 }; 56 | Mat mask = new Mat(h.length, h.length, img.type()); 57 | for (int i = 0; i < h.length; i++) { 58 | for (int j = 0; j < h.length; j++) { 59 | mask.put(i, j, h[i] * h[j]); 60 | } 61 | } 62 | Mat localContrast = new Mat(); 63 | Imgproc.filter2D(img, localContrast, img.depth(), mask); 64 | for (int i = 0; i < localContrast.rows(); i++) { 65 | for (int j = 0; j < localContrast.cols(); j++) { 66 | if (localContrast.get(i, j)[0] > Math.PI / 2.75) 67 | localContrast.put(i, j, Math.PI / 2.75); 68 | } 69 | } 70 | Core.subtract(img, localContrast, localContrast); 71 | return localContrast.mul(localContrast); 72 | } 73 | 74 | public static Mat Exposedness(Mat img) { 75 | double sigma = 0.25; 76 | double average = 0.5; 77 | int rows = img.rows(); 78 | int cols = img.cols(); 79 | Mat exposedness = Mat.zeros(rows, cols, img.type()); 80 | // W = exp(-(img - aver).^2 / (2*sigma^2)); 81 | for (int i = 0; i < rows; i++) { 82 | for (int j = 0; j < cols; j++) { 83 | double value = Math.exp(-1.0 * Math.pow(img.get(i, j)[0] - average, 2.0) / (2 * Math.pow(sigma, 2.0))); 84 | exposedness.put(i, j, value); 85 | } 86 | } 87 | return exposedness; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/utils/ColorBalance.java: -------------------------------------------------------------------------------- 1 | package com.isaac.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.opencv.core.Core; 7 | import org.opencv.core.CvType; 8 | import org.opencv.core.Mat; 9 | 10 | public class ColorBalance { 11 | 12 | /** 13 | * Simplest Color Balance. Performs color balancing via histogram 14 | * normalization. 15 | * 16 | * @param img 17 | * input color or gray scale image 18 | * @param percent 19 | * controls the percentage of pixels to clip to white and black. 20 | * (normally, choose 1~10) 21 | * @return Balanced image in CvType.CV_32F 22 | */ 23 | public static Mat SimplestColorBalance(Mat img, int percent) { 24 | if (percent <= 0) 25 | percent = 5; 26 | img.convertTo(img, CvType.CV_32F); 27 | List channels = new ArrayList(); 28 | int rows = img.rows(); // number of rows of image 29 | int cols = img.cols(); // number of columns of image 30 | int chnls = img.channels(); // number of channels of image 31 | double halfPercent = percent / 200.0; 32 | if (chnls == 3) { 33 | Core.split(img, channels); 34 | } else { 35 | channels.add(img); 36 | } 37 | List results = new ArrayList(); 38 | for (int i = 0; i < chnls; i++) { 39 | // find the low and high precentile values (based on the input percentile) 40 | Mat flat = new Mat(); 41 | channels.get(i).reshape(1, 1).copyTo(flat); 42 | Core.sort(flat, flat, Core.SORT_ASCENDING); 43 | double lowVal = flat.get(0, (int) Math.floor(flat.cols() * halfPercent))[0]; 44 | double topVal = flat.get(0, (int) Math.ceil(flat.cols() * (1.0 - halfPercent)))[0]; 45 | // saturate below the low percentile and above the high percentile 46 | Mat channel = channels.get(i); 47 | for (int m = 0; m < rows; m++) { 48 | for (int n = 0; n < cols; n++) { 49 | if (channel.get(m, n)[0] < lowVal) 50 | channel.put(m, n, lowVal); 51 | if (channel.get(m, n)[0] > topVal) 52 | channel.put(m, n, topVal); 53 | } 54 | } 55 | Core.normalize(channel, channel, 0, 255, Core.NORM_MINMAX); 56 | channel.convertTo(channel, CvType.CV_32F); 57 | results.add(channel); 58 | } 59 | Mat outval = new Mat(); 60 | Core.merge(results, outval); 61 | return outval; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/utils/Filters.java: -------------------------------------------------------------------------------- 1 | package com.isaac.utils; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.opencv.core.Core; 6 | import org.opencv.core.CvType; 7 | import org.opencv.core.Mat; 8 | import org.opencv.core.Scalar; 9 | import org.opencv.core.Size; 10 | import org.opencv.imgproc.Imgproc; 11 | 12 | public class Filters { 13 | 14 | static { 15 | System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 16 | } 17 | 18 | /** 19 | * Guided Image Filter for grayscale image, O(1) time implementation of guided filter 20 | * 21 | * @param I 22 | * guidance image (should be a gray-scale/single channel image) 23 | * @param p 24 | * filtering input image (should be a gray-scale/single channel 25 | * image) 26 | * @param r 27 | * local window radius 28 | * @param eps 29 | * regularization parameter 30 | * @return filtered image 31 | */ 32 | public static Mat GuidedImageFilter(Mat I, Mat p, int r, double eps) { 33 | I.convertTo(I, CvType.CV_64FC1); 34 | p.convertTo(p, CvType.CV_64FC1); 35 | //[hei, wid] = size(I); 36 | int rows = I.rows(); 37 | int cols = I.cols(); 38 | // N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels. 39 | Mat N = new Mat(); 40 | Imgproc.boxFilter(Mat.ones(rows, cols, I.type()), N, -1, new Size(r, r)); 41 | // mean_I = boxfilter(I, r) ./ N; 42 | Mat mean_I = new Mat(); 43 | Imgproc.boxFilter(I, mean_I, -1, new Size(r, r)); 44 | // mean_p = boxfilter(p, r) ./ N 45 | Mat mean_p = new Mat(); 46 | Imgproc.boxFilter(p, mean_p, -1, new Size(r, r)); 47 | // mean_Ip = boxfilter(I.*p, r) ./ N; 48 | Mat mean_Ip = new Mat(); 49 | Imgproc.boxFilter(I.mul(p), mean_Ip, -1, new Size(r, r)); 50 | // cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch. 51 | Mat cov_Ip = new Mat(); 52 | Core.subtract(mean_Ip, mean_I.mul(mean_p), cov_Ip); 53 | // mean_II = boxfilter(I.*I, r) ./ N; 54 | Mat mean_II = new Mat(); 55 | Imgproc.boxFilter(I.mul(I), mean_II, -1, new Size(r, r)); 56 | // var_I = mean_II - mean_I .* mean_I; 57 | Mat var_I = new Mat(); 58 | Core.subtract(mean_II, mean_I.mul(mean_I), var_I); 59 | // a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper; 60 | Mat a = new Mat(); 61 | Core.add(var_I, new Scalar(eps), a); 62 | Core.divide(cov_Ip, a, a); 63 | //b = mean_p - a .* mean_I; % Eqn. (6) in the paper; 64 | Mat b = new Mat(); 65 | Core.subtract(mean_p, a.mul(mean_I), b); 66 | // mean_a = boxfilter(a, r) ./ N; 67 | Mat mean_a = new Mat(); 68 | Imgproc.boxFilter(a, mean_a, -1, new Size(r, r)); 69 | Core.divide(mean_a, N, mean_a); 70 | // mean_b = boxfilter(b, r) ./ N; 71 | Mat mean_b = new Mat(); 72 | Imgproc.boxFilter(b, mean_b, -1, new Size(r, r)); 73 | Core.divide(mean_b, N, mean_b); 74 | // q = mean_a .* I + mean_b; % Eqn. (8) in the paper; 75 | Mat q = new Mat(); 76 | Core.add(mean_a.mul(I), mean_b, q); 77 | //for (int i = 0; i < rows; i++) { 78 | // for (int j = 0; j < cols; j++) { 79 | // if (q.get(i, j)[0] <= 0) 80 | // q.put(i, j, 1.0 / 255); 81 | // } 82 | //} 83 | q.convertTo(q, CvType.CV_32F); 84 | return q; 85 | } 86 | 87 | /** 88 | * Guided Image Filter for Color Image 89 | * @param origI guidance image (should be a gray-scale/single channel image) 90 | * @param p filtering input image (should be a gray-scale/single channel image) 91 | * @param r local window radius 92 | * @param eps regularization parameter 93 | * @param s blocks number, s * s 94 | * @param depth image depth 95 | * @return filtered image 96 | */ 97 | public static Mat GuidedImageFilter_Color(Mat origI, Mat p, int r, double eps, double s, int depth) { 98 | /** 99 | * Pre-defined parameters 100 | */ 101 | ArrayList Ichannels = new ArrayList(); 102 | ArrayList Isubchannels = new ArrayList(); 103 | int Idepth; 104 | double r_sub; 105 | Mat mean_I_r = new Mat(); 106 | Mat mean_I_g = new Mat(); 107 | Mat mean_I_b = new Mat(); 108 | Mat invrr = new Mat(); 109 | Mat invrg = new Mat(); 110 | Mat invrb = new Mat(); 111 | Mat invgg = new Mat(); 112 | Mat invgb = new Mat(); 113 | Mat invbb = new Mat(); 114 | // Process 115 | Mat I; 116 | if (origI.depth() == CvType.CV_32F || origI.depth() == CvType.CV_64F) { 117 | I = origI.clone(); 118 | } else { 119 | I = convertTo(origI, CvType.CV_32F); 120 | } 121 | Idepth = I.depth(); 122 | Core.split(I, Ichannels); 123 | Mat I_sub = new Mat(); 124 | Imgproc.resize(I, I_sub, new Size(I.cols() / s, I.rows() / s), 0.0, 0.0, Imgproc.INTER_NEAREST); 125 | Core.split(I_sub, Isubchannels); 126 | r_sub = r / s; 127 | mean_I_r = boxfilter(Isubchannels.get(0), (int) r_sub); 128 | mean_I_g = boxfilter(Isubchannels.get(1), (int) r_sub); 129 | mean_I_b = boxfilter(Isubchannels.get(2), (int) r_sub); 130 | 131 | // variance of I in each local patch: the matrix Sigma in Eqn (14). 132 | // Note the variance in each local patch is a 3x3 symmetric matrix: 133 | // rr, rg, rb 134 | // Sigma = rg, gg, gb 135 | // rb, gb, bb 136 | Mat var_I_rr = new Mat(); 137 | Mat var_I_rg = new Mat(); 138 | Mat var_I_rb = new Mat(); 139 | Mat var_I_gg = new Mat(); 140 | Mat var_I_gb = new Mat(); 141 | Mat var_I_bb = new Mat(); 142 | Mat temp1 = new Mat(); 143 | 144 | Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(0)), (int) r_sub), 145 | mean_I_r.mul(mean_I_r), temp1); 146 | Core.add(temp1, new Scalar(eps), var_I_rr); 147 | Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(1)), (int) r_sub), 148 | mean_I_r.mul(mean_I_g), var_I_rg); 149 | Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(2)), (int) r_sub), 150 | mean_I_r.mul(mean_I_b), var_I_rb); 151 | Core.subtract(boxfilter(Isubchannels.get(1).mul(Isubchannels.get(1)), (int) r_sub), 152 | mean_I_g.mul(mean_I_g), temp1); 153 | Core.add(temp1, new Scalar(eps), var_I_gg); 154 | Core.subtract(boxfilter(Isubchannels.get(1).mul(Isubchannels.get(2)), (int) r_sub), 155 | mean_I_g.mul(mean_I_b), var_I_gb); 156 | Core.subtract(boxfilter(Isubchannels.get(2).mul(Isubchannels.get(2)), (int) r_sub), 157 | mean_I_b.mul(mean_I_b), temp1); 158 | Core.add(temp1, new Scalar(eps), var_I_bb); 159 | 160 | // Inverse of Sigma + eps * I 161 | Core.subtract(var_I_gg.mul(var_I_bb), var_I_gb.mul(var_I_gb), invrr); 162 | Core.subtract(var_I_gb.mul(var_I_rb), var_I_rg.mul(var_I_bb), invrg); 163 | Core.subtract(var_I_rg.mul(var_I_gb), var_I_gg.mul(var_I_rb), invrb); 164 | Core.subtract(var_I_rr.mul(var_I_bb), var_I_rb.mul(var_I_rb), invgg); 165 | Core.subtract(var_I_rb.mul(var_I_rg), var_I_rr.mul(var_I_gb), invgb); 166 | Core.subtract(var_I_rr.mul(var_I_gg), var_I_rg.mul(var_I_rg), invbb); 167 | 168 | Mat covDet = new Mat(); 169 | Core.add(invrr.mul(var_I_rr), invrg.mul(var_I_rg), temp1); 170 | Core.add(temp1, invrb.mul(var_I_rb), covDet); 171 | 172 | Core.divide(invrr, covDet, invrr); 173 | Core.divide(invrg, covDet, invrg); 174 | Core.divide(invrb, covDet, invrb); 175 | Core.divide(invgg, covDet, invgg); 176 | Core.divide(invgb, covDet, invgb); 177 | Core.divide(invbb, covDet, invbb); 178 | 179 | Mat p2 = convertTo(p, Idepth); 180 | Mat result = new Mat(); 181 | if (p.channels() == 1) { 182 | result = filterSingleChannel(p2, s, Isubchannels, Ichannels, mean_I_r, mean_I_g, mean_I_b, invrr, invrg, 183 | invrb, invgg, invgb, invbb, r_sub); 184 | } else { 185 | ArrayList pc = new ArrayList(); 186 | Core.split(p2, pc); 187 | for (int i = 0; i < pc.size(); i++) { 188 | pc.set(i, filterSingleChannel(pc.get(i), s, Isubchannels, Ichannels, mean_I_r, mean_I_g, mean_I_b, invrr, 189 | invrg, invrb, invgg, invgb, invbb, r_sub)); 190 | } 191 | Core.merge(pc, result); 192 | } 193 | return convertTo(result, depth == -1 ? p.depth() : depth); 194 | } 195 | 196 | private static Mat boxfilter(Mat I, int r) { 197 | Mat result = new Mat(); 198 | Imgproc.blur(I, result, new Size(r, r)); 199 | return result; 200 | } 201 | 202 | private static Mat convertTo(Mat mat, int depth) { 203 | if (mat.depth() == depth) { 204 | return mat; 205 | } 206 | Mat result = new Mat(); 207 | mat.convertTo(result, depth); 208 | return result; 209 | } 210 | 211 | private static Mat filterSingleChannel(Mat p, double s, ArrayList Isubchannels, ArrayList Ichannels, 212 | Mat mean_I_r, Mat mean_I_g, Mat mean_I_b, Mat invrr, Mat invrg, Mat invrb, Mat invgg, Mat invgb, 213 | Mat invbb, double r_sub) { 214 | Mat p_sub = new Mat(); 215 | Imgproc.resize(p, p_sub, new Size(p.cols() / s, p.rows() / s), 0.0, 0.0, Imgproc.INTER_NEAREST); 216 | 217 | Mat mean_p = boxfilter(p_sub, (int) r_sub); 218 | 219 | Mat mean_Ip_r = boxfilter(Isubchannels.get(0).mul(p_sub), (int) r_sub); 220 | Mat mean_Ip_g = boxfilter(Isubchannels.get(1).mul(p_sub), (int) r_sub); 221 | Mat mean_Ip_b = boxfilter(Isubchannels.get(2).mul(p_sub), (int) r_sub); 222 | 223 | // convariance of (I, p) in each local patch 224 | Mat cov_Ip_r = new Mat(); 225 | Mat cov_Ip_g = new Mat(); 226 | Mat cov_Ip_b = new Mat(); 227 | Core.subtract(mean_Ip_r, mean_I_r.mul(mean_p), cov_Ip_r); 228 | Core.subtract(mean_Ip_g, mean_I_g.mul(mean_p), cov_Ip_g); 229 | Core.subtract(mean_Ip_b, mean_I_b.mul(mean_p), cov_Ip_b); 230 | 231 | Mat temp1 = new Mat(); 232 | Mat a_r = new Mat(); 233 | Mat a_g = new Mat(); 234 | Mat a_b = new Mat(); 235 | Core.add(invrr.mul(cov_Ip_r), invrg.mul(cov_Ip_g), temp1); 236 | Core.add(temp1, invrb.mul(cov_Ip_b), a_r); 237 | Core.add(invrg.mul(cov_Ip_r), invgg.mul(cov_Ip_g), temp1); 238 | Core.add(temp1, invgb.mul(cov_Ip_b), a_g); 239 | Core.add(invrb.mul(cov_Ip_r), invgb.mul(cov_Ip_g), temp1); 240 | Core.add(temp1, invbb.mul(cov_Ip_b), a_b); 241 | 242 | Mat b = new Mat(); 243 | Core.subtract(mean_p, a_r.mul(mean_I_r), b); 244 | Core.subtract(b, a_g.mul(mean_I_g), b); 245 | Core.subtract(b, a_b.mul(mean_I_b), b); 246 | 247 | Mat mean_a_r = boxfilter(a_r, (int) r_sub); 248 | Mat mean_a_g = boxfilter(a_g, (int) r_sub); 249 | Mat mean_a_b = boxfilter(a_b, (int) r_sub); 250 | Mat mean_b = boxfilter(b, (int) r_sub); 251 | 252 | Imgproc.resize(mean_a_r, mean_a_r, 253 | new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR); 254 | Imgproc.resize(mean_a_g, mean_a_g, 255 | new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR); 256 | Imgproc.resize(mean_a_b, mean_a_b, 257 | new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR); 258 | Imgproc.resize(mean_b, mean_b, 259 | new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR); 260 | 261 | Mat result = new Mat(); 262 | Core.add(mean_a_r.mul(Ichannels.get(0)), mean_a_g.mul(Ichannels.get(1)), temp1); 263 | Core.add(temp1, mean_a_b.mul(Ichannels.get(2)), temp1); 264 | Core.add(temp1, mean_b, result); 265 | return result; 266 | } 267 | 268 | } 269 | -------------------------------------------------------------------------------- /src/main/java/com/isaac/utils/ImShow.java: -------------------------------------------------------------------------------- 1 | package com.isaac.utils; 2 | 3 | /* 4 | * Author: ATUL 5 | * Thanks to Daniel Baggio , Jan Monterrubio and sutr90 for improvements 6 | * This code can be used as an alternative to imshow of OpenCV for JAVA-OpenCv 7 | * Make sure OpenCV Java is in your Build Path 8 | * Usage : 9 | * ------- 10 | * Imshow ims = new Imshow("Title"); 11 | * ims.showImage(Mat image); 12 | * Check Example for usage with Webcam Live Video Feed 13 | */ 14 | 15 | import java.awt.Dimension; 16 | import java.awt.image.BufferedImage; 17 | import java.awt.image.DataBufferByte; 18 | 19 | //import java.io.ByteArrayInputStream; 20 | //import java.io.InputStream; 21 | //import javax.imageio.ImageIO; 22 | import javax.swing.ImageIcon; 23 | import javax.swing.JFrame; 24 | import javax.swing.JLabel; 25 | //import javax.swing.plaf.ButtonUI; 26 | import javax.swing.WindowConstants; 27 | 28 | import org.opencv.core.Mat; 29 | import org.opencv.core.Size; 30 | import org.opencv.imgproc.Imgproc; 31 | 32 | public class ImShow { 33 | 34 | public JFrame Window; 35 | private ImageIcon image; 36 | private JLabel label; 37 | // private MatOfByte matOfByte; 38 | private Boolean SizeCustom; 39 | private int Height, Width; 40 | 41 | public ImShow(String title) { 42 | Window = new JFrame(); 43 | image = new ImageIcon(); 44 | label = new JLabel(); 45 | // matOfByte = new MatOfByte(); 46 | label.setIcon(image); 47 | Window.getContentPane().add(label); 48 | Window.setResizable(false); 49 | Window.setTitle(title); 50 | SizeCustom = false; 51 | setCloseOption(0); 52 | } 53 | 54 | public ImShow(String title, int height, int width) { 55 | SizeCustom = true; 56 | Height = height; 57 | Width = width; 58 | 59 | Window = new JFrame(); 60 | image = new ImageIcon(); 61 | label = new JLabel(); 62 | // matOfByte = new MatOfByte(); 63 | label.setIcon(image); 64 | Window.getContentPane().add(label); 65 | Window.setResizable(false); 66 | Window.setTitle(title); 67 | setCloseOption(0); 68 | 69 | } 70 | 71 | public void showImage(Mat img) { 72 | if (SizeCustom) { 73 | Imgproc.resize(img, img, new Size(Height, Width)); 74 | } 75 | // Highgui.imencode(".jpg", img, matOfByte); 76 | // byte[] byteArray = matOfByte.toArray(); 77 | BufferedImage bufImage = null; 78 | try { 79 | // InputStream in = new ByteArrayInputStream(byteArray); 80 | // bufImage = ImageIO.read(in); 81 | bufImage = toBufferedImage(img); 82 | image.setImage(bufImage); 83 | Window.pack(); 84 | label.updateUI(); 85 | Window.setVisible(true); 86 | } catch (Exception e) { 87 | e.printStackTrace(); 88 | } 89 | } 90 | 91 | // CREDITS TO DANIEL: http://danielbaggio.blogspot.com.br/ for the improved 92 | // version ! 93 | 94 | public BufferedImage toBufferedImage(Mat m) { 95 | int type = BufferedImage.TYPE_BYTE_GRAY; 96 | if (m.channels() > 1) { 97 | type = BufferedImage.TYPE_3BYTE_BGR; 98 | } 99 | int bufferSize = m.channels() * m.cols() * m.rows(); 100 | byte[] b = new byte[bufferSize]; 101 | m.get(0, 0, b); // get all the pixels 102 | BufferedImage image = new BufferedImage(m.cols(), m.rows(), type); 103 | final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 104 | System.arraycopy(b, 0, targetPixels, 0, b.length); 105 | return image; 106 | 107 | } 108 | 109 | // Thanks to sutr90 for reporting the issue : https://github.com/sutr90 110 | 111 | public void setCloseOption(int option) { 112 | 113 | switch (option) { 114 | case 0: 115 | Window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 116 | break; 117 | case 1: 118 | Window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); 119 | break; 120 | default: 121 | Window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 122 | } 123 | 124 | } 125 | 126 | /** 127 | * Sets whether this window should be resizable or not, by default it is not 128 | * resizable 129 | * 130 | * @param resizable 131 | * true if the window should be resizable, 132 | * false otherwise 133 | */ 134 | public void setResizable(boolean resizable) { 135 | Window.setResizable(resizable); 136 | } 137 | 138 | // Thanks to Jan Monterrubio for additional static methods for viewing images. 139 | 140 | /** 141 | * Displays the given {@link Mat} in a new instance of {@link ImShow} 142 | * 143 | * @param mat 144 | * the {@link Mat} to display 145 | */ 146 | public static void show(Mat mat) { 147 | show(mat, new Dimension(mat.rows(), mat.cols()), "", false, WindowConstants.EXIT_ON_CLOSE); 148 | } 149 | 150 | /** 151 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with 152 | * the given title as the title for the window 153 | * 154 | * @param mat 155 | * the {@link Mat} to display 156 | * @param frameTitle 157 | * the title for the frame 158 | */ 159 | public static void show(Mat mat, String frameTitle) { 160 | show(mat, new Dimension(mat.rows(), mat.cols()), frameTitle, false, WindowConstants.EXIT_ON_CLOSE); 161 | } 162 | 163 | /** 164 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with 165 | * the given title as the title for the window and determines whether the 166 | * frame is resizable or not 167 | * 168 | * @param mat 169 | * the {@link Mat} to display 170 | * @param frameTitle 171 | * the title for the frame 172 | * @param resizable 173 | * whether the frame should be resizable or not 174 | */ 175 | public static void show(Mat mat, String frameTitle, boolean resizable) { 176 | show(mat, new Dimension(mat.rows(), mat.cols()), frameTitle, resizable, WindowConstants.EXIT_ON_CLOSE); 177 | } 178 | 179 | /** 180 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with a 181 | * set size 182 | * 183 | * @param mat 184 | * the {@link Mat} to display 185 | * @param frameSize 186 | * the size for the frame 187 | */ 188 | public static void show(Mat mat, Dimension frameSize) { 189 | show(mat, frameSize, "", false, WindowConstants.EXIT_ON_CLOSE); 190 | } 191 | 192 | /** 193 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with a 194 | * set size and given title 195 | * 196 | * @param mat 197 | * the {@link Mat} to display 198 | * @param frameSize 199 | * the size for the frame 200 | * @param frameTitle 201 | * the title for the frame 202 | */ 203 | public static void show(Mat mat, Dimension frameSize, String frameTitle) { 204 | show(mat, frameSize, frameTitle, false, WindowConstants.EXIT_ON_CLOSE); 205 | } 206 | 207 | /** 208 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with a 209 | * set size and given title and whether it is resizable or not 210 | * 211 | * @param mat 212 | * the {@link Mat} to display 213 | * @param frameSize 214 | * the size for the frame 215 | * @param frameTitle 216 | * the title for the frame 217 | */ 218 | public static void show(Mat mat, Dimension frameSize, String frameTitle, boolean resizable) { 219 | show(mat, frameSize, frameTitle, resizable, WindowConstants.EXIT_ON_CLOSE); 220 | } 221 | 222 | /** 223 | * Displays the given {@link Mat} in a new instance of {@link ImShow} with a 224 | * set size and given title and whether it is resizable or not, and with the 225 | * close operation set 226 | * 227 | * @param mat 228 | * the {@link Mat} to display 229 | * @param frameSize 230 | * the size for the frame 231 | * @param frameTitle 232 | * the title for the frame 233 | * @param resizable 234 | * wether the frame is resizable or not 235 | * @param closeOperation 236 | * the constant for the default close operation of the frame 237 | */ 238 | public static void show(Mat mat, Dimension frameSize, String frameTitle, boolean resizable, int closeOperation) { 239 | ImShow frame = new ImShow(frameTitle, frameSize.height, frameSize.width); 240 | frame.setResizable(resizable); 241 | 242 | /* 243 | * This is a bad way to access the window, but due to legacy stuff I 244 | * won't change the access patterns 245 | */ 246 | frame.Window.setDefaultCloseOperation(closeOperation); 247 | frame.showImage(mat); 248 | } 249 | 250 | } 251 | -------------------------------------------------------------------------------- /target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: zhanghao 3 | Build-Jdk: 1.8.0_121 4 | Created-By: Maven Integration for Eclipse 5 | 6 | -------------------------------------------------------------------------------- /target/classes/META-INF/maven/com.isaac.enhance/ImageEnhanceViaFusion/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Sat Mar 04 13:25:28 SGT 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.isaac.enhance 5 | m2e.projectName=ImageEnhanceViaFusion 6 | m2e.projectLocation=/Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion 7 | artifactId=ImageEnhanceViaFusion 8 | -------------------------------------------------------------------------------- /target/classes/META-INF/maven/com.isaac.enhance/ImageEnhanceViaFusion/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.isaac.enhance 6 | ImageEnhanceViaFusion 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | ImageEnhanceViaFusion 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | junit 20 | junit 21 | 3.8.1 22 | test 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven 2 | #Thu Mar 02 09:59:55 CST 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.isaac.enhance 5 | artifactId=ImageEnhanceViaFusion 6 | -------------------------------------------------------------------------------- /target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/26hzhang/ImageEnhanceViaFusion/f8f1644bdfcebfd7382429fc1579652b099d2c15/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst -------------------------------------------------------------------------------- /target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/enhance/EnhanceFunc.java 2 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/enhance/Pyramid.java 3 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/enhance/WeightCalculate.java 4 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/utils/ImShow.java 5 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/utils/Filters.java 6 | /Users/zhanghao/Documents/Java/workspace/ImageEnhanceViaFusion/src/main/java/com/isaac/utils/ColorBalance.java 7 | --------------------------------------------------------------------------------