Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaFXとOpenCVで画像の明るさとコントラストを変更する方法


OpenCVのorg.opencv.core.Matクラスが提供するconvertTo()メソッドを使うと、画像の明るさやコントラストを簡単に調整できます。このメソッドは、出力先の行列(空のMat)、出力データ型(rtype)、ゲイン(alpha)、オフセット(beta)の順に4つの引数を受け取ります。

各ピクセルの値は「α × 元の画素値 + β」という式で変換されるため、alphaでコントラストbetaで明るさがそれぞれ制御されます。具体的な調整方法は以下の通りです。

  • 明るさを上げる場合:beta値を0から正方向(最大255)へ増やします(alpha値は1のまま)。

  • 明るさを下げる場合:beta値を0から負方向(最小-255)へ減らします(alpha値は1のまま)。

  • コントラストを上げる場合:alpha値を1から大きくしていきます(beta値は0のまま)。

  • コントラストを下げる場合:alpha値を1から0に向かって小さくしていきます(beta値は0のまま)。

サンプルプログラム

以下は、2つのスライダーでalpha値とbeta値を操作し、画像の見た目をリアルタイムに変化させるJavaFXプログラムの例です。スライダーを動かすたびにChangeListenerが呼び出され、convertTo()による変換結果がImageViewに即座に反映されます。

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
public class AlphaBetaValuesJavaFX extends Application {
    double contrast = 1;
    private final int rtype = -1;
    double alpha = 1;
    double beta = 0;
    Slider slider1;
    Slider slider2;
    Mat src = null;
    public void start(Stage stage) throws IOException {
        //OpenCVのコアライブラリを読み込む
        System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
        String file ="D:\\Image\\lamma2.jpg";
        src = Imgcodecs.imread(file);
        WritableImage writableImage = loadImage(src);
        //ImageViewの設定
        ImageView imageView = new ImageView(writableImage);
        imageView.setX(50);
        imageView.setY(25);
        imageView.setFitHeight(400);
        imageView.setFitWidth(550);
        imageView.setPreserveRatio(true);
        Label label1 = new Label("Alpha value");
        //スライダーの設定
        slider1 = new Slider(0.1, 3, 1);
        slider1.setShowTickLabels(true);
        slider1.setShowTickMarks(true);
        slider1.setMajorTickUnit(1);
        slider1.setBlockIncrement(0.05);
        //ラベルの設定
        Label label2 = new Label();
        Label label3 = new Label("Beta value");
        //スライダーの設定
        slider2 = new Slider(-100, 100, 0);
        slider2.setShowTickLabels(true);
        slider2.setShowTickMarks(true);
        slider2.setMajorTickUnit(25);
        slider2.setBlockIncrement(10);
        //ラベルの設定
        Label label4 = new Label();
        //スライダー用のリスナー
        slider1.valueProperty().addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue <?extends Number>observable, Number oldValue, Number newValue){
                try {
                    label2.setText("&alpha;-value: " + newValue);
                    alpha = newValue.doubleValue();
                    Mat dest = new Mat(src.rows(), src.cols(), src.type());
                    src.convertTo(dest, rtype, alpha, beta);
                    imageView.setImage(loadImage(dest));
                }
                catch(Exception e) {
                    System.out.println("");
                }
            }
        });
        slider2.valueProperty().addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue <?extends Number>observable, Number oldValue, Number newValue){
                try {
                    label4.setText("&beta;-value: " + newValue);
                    beta = newValue.doubleValue();
                    Mat dest = new Mat(src.rows(), src.cols(), src.type());
                    src.convertTo(dest, rtype, alpha, beta);
                    imageView.setImage(loadImage(dest));
                }
                catch(Exception e) {
                    System.out.println("");
                }
            }
        });
        //3つのコンポーネントを配置するVBox
        VBox vbox = new VBox();
        vbox.setPadding(new Insets(20));
        vbox.setSpacing(10);
        vbox.getChildren().addAll(label1, slider1, label2, imageView, label3, slider2, label4);
        //シーンオブジェクトの作成
        Scene scene = new Scene(vbox, 600, 580);
        stage.setTitle("Loading an image");
        stage.setScene(scene);
        stage.show();
    }
    public WritableImage loadImage(Mat image) throws IOException {
        MatOfByte matOfByte = new MatOfByte();
        Imgcodecs.imencode(".jpg", image, matOfByte);
        //エンコードしたMatをバイト配列に格納
        byte[] byteArray = matOfByte.toArray();
        //画像の表示
        InputStream in = new ByteArrayInputStream(byteArray);
        BufferedImage bufImage = ImageIO.read(in);
        System.out.println("Image Loaded");
        WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
        return writableImage;
    }
    public static void main(String args[]) {
        launch(args);
    }
}

入力画像

JavaFXとOpenCVで画像の明るさとコントラストを変更する方法

出力結果

JavaFXとOpenCVで画像の明るさとコントラストを変更する方法

  1. Java OpenCVライブラリを使って画像の明るさを変更する方法

    OpenCVのorg.opencv.core.Matクラスが提供するconvertTo()メソッドを使うと、行列に対して必要な演算を実行し、画像のコントラストや明るさを簡単に調整できます。このメソッドは以下の4つのパラメータを受け取ります。 mat − 計算結果を格納するための空の行列。ソース行列と同じサイズ・型である必要があります。 rtype − 出力行列の型を指定する整数値。負の値を指定した場合は、ソース行列と同じ型になります。 alpha − ゲイン値。0より大きい値を指定します(デフォルトは1)。この値を変更するとコントラストに影響します。 beta − バイアス値(デフォルトは

  2. 【Java】OpenCVライブラリを使って画像のコントラストを変更する方法

    画像の明るさやコントラストの増減は、画像のピクセル値を変換することで実現できます。この変換は、次のような数式で表されます。g(i, j) = α ・ f(i, j) + βここで、各要素の意味は以下のとおりです。(i, j):ピクセルの位置(座標)α(ゲイン)と β(バイアス):変換のパラメータ一般に、ゲインパラメータ α が画像のコントラストを制御し、バイアスパラメータ β が画像の明るさを制御します。convertTo() メソッドについてorg.opencv.core.Mat クラスの convertTo() メソッドを使うと、指定した行列に対して必要な計算を実行し、画像のコントラストや