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

OpenCVとJavaFXで画像の鮮明さを変更するアプリケーションの作成方法


画像のシャープ化(鮮明化)は、ぼかし処理とは正反対の操作です。OpenCVライブラリを使って画像の鮮明さを変更するには、まずガウシアンフィルタで元画像を平滑化(ぼかし)し、次にその平滑化した画像を元画像から減算します。この処理により、輪郭やディテールが強調され、画像全体がくっきりとした印象になります。

仕組みのポイント

本記事のサンプルでは、Core.addWeighted()メソッドを使って元画像と平滑化画像を加重合成しています。第2引数のalphaは元画像の重み、第4引数のbetaは平滑化画像の重みです。betaを負の値に設定すると、平滑化成分が元画像から差し引かれ、シャープ化効果が得られます。

実装例

以下は、alpha値とbeta値をそれぞれ調整できる2つのスライダーを備えたJavaFXアプリケーションのサンプルコードです。スライダーを動かすと、画像の鮮明さがリアルタイムで変化します。

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.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class SharpnessJavaFX 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 = 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(-2, 2, 0);
      slider2.setShowTickLabels(true);
      slider2.setShowTickMarks(true);
      slider2.setMajorTickUnit(1);
      slider2.setBlockIncrement(.5);
      //ラベルの設定
      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());
               Imgproc.GaussianBlur(src, dest, new Size(0,0), 10);
               Core.addWeighted(src, alpha, dest, beta, 0, dest);
               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());
               Imgproc.GaussianBlur(src, dest, new Size(0,0), 10);
               Core.addWeighted(src, alpha, dest, beta, 0, dest);
               imageView.setImage(loadImage(dest));
            }
            catch(Exception e) {
               System.out.println("");
            }
         }
      });
      //すべてのコンポーネントを配置する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, 560);
      stage.setTitle("Altering the sharpness");
      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);
   }
}

入力画像

OpenCVとJavaFXで画像の鮮明さを変更するアプリケーションの作成方法

出力画像

OpenCVとJavaFXで画像の鮮明さを変更するアプリケーションの作成方法

  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() メソッドを使うと、指定した行列に対して必要な計算を実行し、画像のコントラストや