I was simply looking for some Java code to turn the a picture into its Sepia version and realized most of the java examples were a bit lacking.
Turning a picture to Sepia is just toning down values for the different B(lue), G(reen), R(ed) channels of the picture. We are using a 3x3 kernel on the input Mat object and apply the kernel transformation using OpenCv’s transform.
Using any of the origami template available you can start typing in your language of choice.
Java Code
The java version is actually surprisingly readable and short. Note that this also works in a Jupter notebook, as we described in
package me;
import java.io.File;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.scijava.nativelib.NativeLoader;
/**
* Using a kernel to get sepia picture
*/
public class Sepia {
public static void main(String[] args) throws Exception {
NativeLoader.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat source = Imgcodecs.imread("data/marcel.jpg");
// mat is in BGR
Mat kernel = new Mat(3, 3, CvType.CV_32F);
kernel.put(0, 0,
// green
0.272, 0.534, 0.131,
// blue
0.349, 0.686, 0.168,
// red
0.393, 0.769, 0.189);
Mat destination = new Mat();
Core.transform(source, destination, kernel);
String output = "target/sepia2_" + new File(filename).getName();
Imgcodecs.imwrite(output, destination);
}
}
Kotlin Code
Using IntelliJ’s convert to Kotlin code, we get something that is slightly shorter and remove some of the boiler plate code. Actually not much … but still.
import java.io.IOException
import org.opencv.core.Core
import org.opencv.core.CvType
import org.opencv.core.Mat
import org.opencv.imgcodecs.Imgcodecs
import org.scijava.nativelib.NativeLoader
class Sepia {
@Throws(IOException::class)
fun run(input: String, output: String) {
// sepia kernel
val kernel = Mat(3, 3, CvType.CV_32F)
kernel.put(0, 0,
0.272, 0.534, 0.131,
0.349, 0.686, 0.168,
0.393, 0.769, 0.189)
val destination = Mat()
Core.transform(Imgcodecs.imread(input), destination, kernel)
Imgcodecs.imwrite(output, destination)
}
companion object {
@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
NativeLoader.loadLibrary(Core.NATIVE_LIBRARY_NAME)
Sepia().run("data/marcel.jpg", "target/marcel_sepia.jpg")
println("A new sepia cat is in target/marcel_sepia.jpg")
}
}
}
pure origami / clojure code
Of course, my favourite is still in Origami clojure when we can make full use of the Clojure threading macros:
(ns sepia
(:require
[opencv4.utils :as u]
[opencv4.core :refer :all]))
(-> "data/marcel.jpg"
(imread)
(transform!
(u/matrix-to-mat [
[0.272 0.534 0.131]
[0.349 0.686 0.168]
[0.393 0.769 0.189]]))
(u/imshow))
In All three cases, Marcel goes from colored
to sepia …
The three samples can be found in the java tutorial section of Origami. clj, kotlin and java