private void Start() { var src = Util.LoadTexture("imori_dark", CvType.CV_8UC3); var dst = new Mat(src.rows(), src.cols(), CvType.CV_8UC3); var meanMat = new MatOfDouble(); var stdDevMat = new MatOfDouble(); var s0 = (byte)52; var m0 = (byte)128; Core.meanStdDev(src, meanMat, stdDevMat); var meansEachColor = meanMat.toArray(); var stdDevsEachColor = stdDevMat.toArray(); var totalMean = (int)meansEachColor.Average(); var totalStdDev = (int)Math.Sqrt((stdDevsEachColor.Select(x => x * x).Sum() + meansEachColor.Select(x => x * x).Sum()) / 3d - totalMean * totalMean); for (var x = 0; x < src.width(); x++) { for (var y = 0; y < src.height(); y++) { var col = new byte[src.channels()]; src.get(x, y, col); for (var c = 0; c < src.channels(); c++) { col[c] = (byte)(s0 / totalStdDev * (col[c] - totalMean) + m0); } dst.put(x, y, col); } } GetComponent <Renderer>().material.mainTexture = Util.MatToTexture2D(dst); }
// Super fast color transfer between images. (Slightly faster than processing in Lab color format) private void TransferColor_YCrCb(Mat source, Mat target, Mat mask) { bool is4chanelColor = false; if (source.channels() == 4) { if (sourceMat_c3 == null) { sourceMat_c3 = new Mat(); } if (targetMat_c3 == null) { targetMat_c3 = new Mat(); } is4chanelColor = true; Imgproc.cvtColor(source, sourceMat_c3, Imgproc.COLOR_RGBA2RGB); Imgproc.cvtColor(target, targetMat_c3, Imgproc.COLOR_RGBA2RGB); } else { sourceMat_c3 = source; targetMat_c3 = target; } if (sourceMatYCrCb == null) { sourceMatYCrCb = new Mat(); } if (targetMatYCrCb == null) { targetMatYCrCb = new Mat(); } Imgproc.cvtColor(sourceMat_c3, sourceMatYCrCb, Imgproc.COLOR_RGB2YCrCb); Imgproc.cvtColor(targetMat_c3, targetMatYCrCb, Imgproc.COLOR_RGB2YCrCb); MatOfDouble labMeanSrc = new MatOfDouble(); MatOfDouble labStdSrc = new MatOfDouble(); Core.meanStdDev(sourceMatYCrCb, labMeanSrc, labStdSrc, mask); MatOfDouble labMeanTar = new MatOfDouble(); MatOfDouble labStdTar = new MatOfDouble(); Core.meanStdDev(targetMatYCrCb, labMeanTar, labStdTar, mask); targetMatYCrCb.convertTo(targetMatYCrCb, CvType.CV_32FC3); // subtract the means from the target image double[] labMeanTarArr = labMeanTar.toArray(); Core.subtract(targetMatYCrCb, new Scalar(labMeanTarArr[0], labMeanTarArr[1], labMeanTarArr[2]), targetMatYCrCb); // scale by the standard deviations double[] labStdTarArr = labStdTar.toArray(); double[] labStdSrcArr = labStdSrc.toArray(); Scalar scalar = new Scalar(labStdTarArr[0] / labStdSrcArr[0], labStdTarArr[1] / labStdSrcArr[1], labStdTarArr[2] / labStdSrcArr[2]); Core.multiply(targetMatYCrCb, scalar, targetMatYCrCb); // add in the source mean double[] labMeanSrcArr = labMeanSrc.toArray(); Core.add(targetMatYCrCb, new Scalar(labMeanSrcArr[0], labMeanSrcArr[1], labMeanSrcArr[2]), targetMatYCrCb); // clip the pixel intensities to [0, 255] if they fall outside this range. //Imgproc.threshold (targetMatYCrCb, targetMatYCrCb, 0, 0, Imgproc.THRESH_TOZERO); //Imgproc.threshold (targetMatYCrCb, targetMatYCrCb, 255, 255, Imgproc.THRESH_TRUNC); targetMatYCrCb.convertTo(targetMatYCrCb, CvType.CV_8UC3); Imgproc.cvtColor(targetMatYCrCb, targetMat_c3, Imgproc.COLOR_YCrCb2RGB); if (is4chanelColor) { Imgproc.cvtColor(targetMat_c3, target, Imgproc.COLOR_RGB2RGBA); } }