20190527のJavaに関する記事は30件です。

MyBatisでUpdate文をループさせようとしてハマった件

はじめに

筆者は今年やっと業務2年目に突入したまだまだビギナーなエンジニアです。

なので、記事のレベルはあまり高くないですが、

業務でコードを書いた際にハマった点をこれから来る後輩向けに残したい!!

→どうせ残すならQiitaで書きたい!!と思い投稿してみました。

今回ハマった背景

Spring+MyBatisでバックエンド開発を行っていたときの話です。

担当した機能でリクエストから送られてきたn件のオブジェクトを、

ロジックを通した後にMyBatisを用いて複数件Updateするということをやりました。

その前にMyBatisって?

今回の話をする前に軽くMyBatisの話をします。

MyBatisとは、XMLにSQLを記述する形式のORマッパーフレームワークです。

ORマッパーの中には、わざわざSQLを開発者が書かなくても、
通常のCRUD処理が担保されているものもありますが、

MyBatisはあえて、SQLを手書きすることで複雑な結合や、
UPSERT文などの特殊なSQLをJavaオブジェクトとマッピングができたり、
SQL分の中にif文やforeach等が書け、動的なSQLを生成することができます。

例) INSERT文だと以下のような書き方ができます。

Javaファイル
public interface UserRepository{
    public int insertUser(List<User> userList);
}
XMLファイル
<insert id="insertUser" parameterType="java.util.List">
   INSERT INTO users ( 
          user_id
        , user_name
        , user_mail
   )
   VALUES
   <foreach item="user" collection="list" open="" separator="," close="">
     (
        #{userId, jdbcType=BIGINT},
        #{userName, jdbcType=VARCHAR},
        #{userEmail, jdbcType=VARCHAR},
     )
   </foreach>
 </insert>

上記だと、登録したい値をUserオブジェクトに詰めておき、
それらをListにしてORマッパーに渡すことで、1度のクエリ発行で複数のINSERTが可能です。
この1度の発行というのが良く、DBとのアクセス回数を絞ることでパフォーマンスを下げないで済みます。

Updateでハマる

上記のノリでUpdateもループで回そう!とやるとハマります。

事象

具体的には以下のようなSQLを書いた場合です。(Javaは割愛)

XMLファイル
<update id ="updateUser" parameterType= "java.util.List" >
     <foreach collection ="itemList" item="item" separator= ";">
          update users
           <set >
                user_name = #{userName, jdbcType=VARCHAR},
                user_email = #{userEmail, jdbcType=VARCHAR}
           </set >
          WHERE user_id = #{userId,}
     </foreach >
</update >

例えば、上記SQLで「あああ」さんと「いいい」さんの更新をするとします。
これによって発行されるクエリは以下のようになります。

発行されるSQL
update users
    user_name = 'あああ',
    user_email = 'aaa@aaa.com'
where user_id = '001';
update users
    user_name = 'いいい',
    user_email = 'iii@iii.com'
where user_id = '002';

一見良さげに見えますが、実際に処理を行おうとするとエラーになります。
しかし、この発行されたSQLをテーブルに直接流すと正常に処理が終了します。

原因

これはMybatisというか、Javaのメソッドという面で考えれば納得がいきます(少なくても筆者は)

Javaの挙動として、updateUserというメソッドを呼ぶことになるのですが、
その中でクエリをn件発行しDBへのアクセス行います。

この際、1回のクエリ発行による処理件数を返り値として呼び元のクラスに返すのですが、
上記Update文の場合、一度のメソッド呼びだしで複数のクエリが発行されるので、
複数の返り値を返そうとしてしまいエラーとなります。

なぜInsertはforeachできるのか

これはMyBatisの話をした箇所で書いたとおり、Insert文の場合は
1回のクエリ発行で複数の処理を行うため、
1度のメソッド呼び出しで2件登録したとしても、
返り値が「2」となるだけで、返り値の個数は1つなので正常に処理が終了します。

どうやってUpdateでループするのか

mySQLなどのUPSERT文が使用できるDBならDUPLICATE KEYの記述をし、
UPSERTにしてしまうことで解決できます。

UPSERT処理例
<insert id="upsertUser" parameterType="java.util.List">
    INSERT INTO users ( 
          user_id
        , user_name
        , user_mail
   )
   VALUES
   <foreach item="user" collection="list" open="" separator="," close="">
     (
        #{userId, jdbcType=BIGINT},
        #{userName, jdbcType=VARCHAR},
        #{userEmail, jdbcType=VARCHAR},
     )
   </foreach>
   ON DUPLICATE KEY UPDATE
     user_name = VALUES(userName),
     user_email = VALUES(userEmail)
 </insert>

上記SQLだと、更新対象のオブジェクトからでも一旦はINSERT文が発行されます。
これを実行すると、実行時に一意成約違反になるINSERT文の場合、
ON DUPLICATE KEY UPDATEに記述されたUpdate文に切り替わるという処理となります。
よってn件の更新用オブジェクトをこの処理に渡すと、
結果的に一度のクエリ発行で結果的に複数の更新ができることになり処理が正常に行われます。

おわりに

最後まで読んでいただきありがとうございます。
おかしな部分がありましたら、ご指摘お願いします。
また、これからも記事投稿してこうと思うので、執筆についてにアドバイスなども大歓迎です!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC - 014- A&B&C

AtCoder ABC 014 A&B&C

AtCoder - 014

A - けんしょう先生のお菓子配り

    private void solveA() {
        int a = nextInt();
        int b = nextInt();
        int mod = a % b;
        out.println(mod == 0 ? 0 : b - mod);
    }

B - 価格の合計

  • xのどの位置のbitが1なのか?
    • bitが1の位置を商品価格のindexと対応させる
    private void solveB() {
        int n = nextInt();
        int x = nextInt();
        int[] wk = IntStream.range(0, n).map(i -> nextInt()).toArray();

        int sum = 0;
        int index = 0;
        while (x != 0) {
            if ((x & 1) == 1) {
                sum += wk[index];
            }
            x >>= 1;
            index++;
        }

        out.println(sum);
    }

C - AtColor

  • 累積和をとってしまえば簡単なんだけど。。。別解思いつかないなぁ
    private void solveC() {
        int n = nextInt();
        int[][] wk = Stream.generate(() -> new int[] { nextInt(), nextInt() }).limit(n).toArray(int[][]::new);

        int[] imos = new int[1000001];
        for (int i = 0; i < n; i++) {
            imos[wk[i][0]] += 1;
            if (wk[i][1] + 1 < imos.length) {
                imos[wk[i][1] + 1] -= 1;
            }
        }
        for (int i = 1; i < imos.length; i++) {
            imos[i] = imos[i] + imos[i - 1];
        }

        Arrays.sort(imos);
        out.println(imos[imos.length - 1]);
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Why should you learn java language

  1. Java is Simple: The Java programming language is easy to learn. Java code is easy to read and write.
  2. Java is Familiar: Java is similar to C/C++ but it removes the drawbacks and complexities of C/C++ like pointers and multiple inheritances. So if you have a background in C/C++, you will find Java familiar and easy to learn.
  3. Java is an Object-Oriented programming language: Unlike C++ which is semi object-oriented, Java is a fully object-oriented programming language. It has all OOP features such as abstraction, encapsulation, inheritance, and polymorphism.
  4. Java supports Functional programming: Since Java SE version 8 (JDK 8), Java is updated with functional programming features like functional interfaces and Lambda Expressions. This increases the flexibility of Java.
  5. Java is Robust: With automatic garbage collection and simple memory management model (no pointers like C/C++), plus language features like generics, try-with-resources,… Java guides programmer toward reliable programming habits for creating highly reliable applications.
  6. Java is Secure: The Java platform is designed with security features built into the language and runtime system such as static type-checking at compile time and runtime checking (security manager), which let you create applications that can't be invaded from outside. You never hear about viruses attacking Java applications.
  7. Java is High Performance: Java code is compiled into bytecode which is highly optimized by the Java compiler so that the Java virtual machine (JVM) can execute Java applications at full speed. In addition, the compute-intensive code can be re-written in native code and interfaced with Java platform via Java Native Interface (JNI) thus improve the performance.
  8. Java is Multithreaded: The Java platform is designed with multithreading capabilities built into the language. That means you can build applications with many concurrent threads of activity, resulting in highly interactive and responsive applications.
  9. Java is Platform Independence: Java code is compiled into an intermediate format (bytecode), which can be executed on any systems for which Java virtual machine is ported. That means you can write a Java program once and run it on Windows, Mac, Linux or Solaris without re-compiling. Thus the slogan "Write once, run anywhere" of Java. Besides the above features, programmers can benefit from a strong and vibrant Java ecosystem: Java is powered by Oracle - one of the leaders in the industry. Java also gets enormous support from big technology companies like IBM, Google, Redhat,… so it has been always evolving over the years. There are a lot of open source libraries which you can choose for building your applications. There are many superior tools and IDEs that make your Java development easier. There are many frameworks that help you build highly reliable applications quickly. The community around Java technology is very big and mature so that you can get support easily.

Related blog:

Java training institute in chennai

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】日付型変換

やりたいこと

  • 頻繁に使う下記5つの型の変換方法を記載
    • String
    • java.util.Date
    • java.sql.Date
    • LocalDate
    • LocalDateTime

String

-> java.util.Date

    //  変換 : SimpleDateFormat
    //  例外 : ParseException
    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    date = format.parse("2019/04/01");

-> java.sql.Date

    // 変換 : なし
    // 例外 : なし
    // 区切り文字は「ハイフン(-)のみ許容」
  java.sql.Date sqlDate= java.sql.Date.valueOf("2019-04-01");

-> LocalDate

    // 変換 : DateTimeFormatter
    // 例外 : なし (DateTimeParseException) 
    LocalDate.parse("2019/4/1", DateTimeFormatter.ofPattern("yyyy/MM/dd")); // 0埋め必須 (例外発生)
    LocalDate.parse("2019/4/1", DateTimeFormatter.ofPattern("yyyy/M/d")) ;   // 0埋め不要

-> LocalDateTime

    // 変換 : DateTimeFormatter
    // 例外 : なし (DateTimeParseException)
    LocalDateTime.parse("2019/04/01", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));

java.util.Date

-> String

    // 変換 : SimpleDateFormat 
    // 例外 : なし
    SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
    format.format(new Date());

-> java.sql.Date

    // 変換 : なし
    // 例外 : なし
    // ポイント : いったんミリ秒 (エポック時間:1970年からの経過時間を引数にする。)
    java.sql.Date sqlDate = new java.sql.Date(new java.util.Date().getTime());

-> LocalDate

    // 変換 : Instant, ZoneDateTime
    // 例外 : なし
    Date date = new Date();
    LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

-> LocalDateTime

    // 変換 : Instant, ZoneDateTime
    // 例外 : なし
    LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

java.sql.Date

-> String

    // 変換 - 
    // 例外 - 
    java.sql.Date date = java.sql.Date.valueOf("2019-04-01");
    String strDate = date.toString();

-> java.util.Date

    ★明日書きます。

-> LocalDate

 ★明日書きます。

-> LocalDateTime

 ★明日書きます。

LocalDate

-> String

    // 変換 : DateTimeFormatter
    // 例外 : なし
    LocalDate localDate = LocalDate.of(2019, 04, 01);
    String strDate = localDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));

-> java.util.Date

    // 変換 : SimpleDateFormat
    // 例外 : ParseException
    // ポイント : LocalDate -> String -> Date
  localDate = LocalDate.of(2019, 04, 01);
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    date = format.parse(localDate.toString());

-> java.sql.Date

    // 変換 : -
    // 例外 : -
    LocalDate localDate = LocalDate.of(2019, 04, 01);
    java.sql.Date sqlDate = java.sql.Date.valueOf(localDate);

-> LocalDateTime

    // 変換 : -
    // 例外 : -
    // ポイント : 時分秒は00:00:00
    LocalDate localDate = LocalDate.of(2019, 04, 01);    
    LocalDateTime localDateTime = localDate.atStartOfDay();

LocalDateTime

-> String

    // 変換 : DateTimeFormatter
    // 例外 : -
    LocalDateTime localDate = LocalDateTime.of(2019, 04, 01, 23, 59, 58);
    String strDate = localDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm:ss"));

-> java.util.Date

    // 変換 : LocalDateTime -> ZonedDateTime -> Instant -> Date
    // 例外 -
    LocalDateTime localDateTime = LocalDateTime.of(2019, 04, 01, 23, 59, 58);
    Date date = Date.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()).toInstant());

-> java.sql.Date

    // 変換 : LocalDateTime -> LocalDate -> sql.Date
    // 例外 : -
    LocalDateTime localDateTime = LocalDateTime.of(2019, 04, 01, 23, 59, 58);
    java.sql.Date sqlDate = java.sql.Date.valueOf(localDateTime.toLocalDate());

-> LocalDate

    // 変換 : -
    // 例外 : -
    LocalDateTime localDateTime = LocalDateTime.of(2019, 04, 01, 23, 59, 58);
    LocalDate localDate = localDateTime.toLocalDate();

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Mavenでwarのファイル名を設定したものに固定にする

Maven2を使っているときに、デフォルトのpom.xmlだと出力されるwarのファイル名にファイルにバージョンが自動的に付与されてしまう。

ex) sampleapp-0.0.0.war

Tomcatのwebappsにひょいってデプロイしたいときにこんなファイル名だとめんどくさいので、
そんな時は pom.xml内に以下の設定を追加するとファイル名が固定になる。

pom.xml
<build>
    (略)
     <finalName>sampleapp</finalName>
     <!--↑この行追加 -->
</build>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Decolor

Goal

Test OpenCV decolor.

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.photo.Photo;

import javax.swing.*;
import java.awt.*;

public class OpenCV_Decolor {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =5;
    double beta =50;

    /**
     *  Launch the application.
     */

    public static void main(String[] args){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat im = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");
        Mat color_boost=new Mat();
        Mat grayscale=new Mat();
        Photo.decolor(im, grayscale, color_boost);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_boost.jpg", color_boost);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_boost_gray.jpg", grayscale);
    }
}
Result

lena_boost.jpg

lena_boost_gray.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Inpaint

Goal

Test OpenCV inpaint.

OpenCV_PotoInpaint.java
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Panel;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import java.awt.Color;
import java.awt.image.BufferedImage;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.photo.Photo;

import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class OpenCV_PotoInpaint {

    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha = 2;
    double beta =50;

    /**
     *  Launch tje application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_PotoInpaint window = new OpenCV_PotoInpaint();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_PotoInpaint() {
        initialize();
        System.out.println("Photo.INPAINT_NS="+ Photo.INPAINT_NS);
        System.out.println("Photo.INPAINT_TELEA="+Photo.INPAINT_TELEA);
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_dirty.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("影像修復");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 438, 438);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        JButton btnNewButton = new JButton("影像修復");

        btnNewButton.setBounds(326, 10, 87, 23);
        frmjavaSwing.getContentPane().add(btnNewButton);

        JLabel lblNewLabel_1 = new JLabel("flag");
        lblNewLabel_1.setBounds(10, 14, 46, 15);
        frmjavaSwing.getContentPane().add(lblNewLabel_1);

        final JSlider slider = new JSlider();

        slider.setValue(0);
        slider.setMaximum(1);
        slider.setBounds(37, 8, 63, 25);
        frmjavaSwing.getContentPane().add(slider);

        final JLabel label = new JLabel("0");
        label.setBounds(114, 14, 46, 15);
        frmjavaSwing.getContentPane().add(label);

        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                label.setText(slider.getValue()+"");

            }
        });
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                BufferedImage newImage=matToBufferedImage(photoInpaint(source,slider.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });

    }

    public Mat photoInpaint(Mat source,int flag){
        Mat destination=new Mat(source.rows(),source.cols(), CvType.CV_8UC3);
        Mat maskMat= Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_dirtymask.jpg",0);
        Photo.inpaint(source, maskMat, destination, 1, Photo.INPAINT_NS);
        return destination;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}
Result

lena_dirty.jpg

lena_dirtymask.jpg

opencv_inpaint.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

kotlinでtry-with-resourcesするやつ

いきなり結論

残念ながらkotlinにはtry-with-resourcesそのものはないです。
その代わり、同等のfunction(厳密にはextension function: 拡張関数)としてuseがあります。

java
try (OutputStream ost = Files.newOutputStream(path)) {
    FileCopyUtils.copy(inst, ost);
} catch (Exception e) {
    e.printStackTrace();
}

これが↓

kotlin
try {
    Files.newOutputStream(path).use { ost ->
        FileCopyUtils.copy(inst, ost)
    }
} catch (e: Exception) {
    e.printStackTrace()
}

こうなります。

個人的にはuseの中身が1行であればFiles.newOutputStream(path).use { ost -> FileCopyUtils.copy(inst, ost) }みたいに改行せずに書くことが多いです。
kotlinはjavaに比べてスッキリと書けるのところが好きなので。

複数resourceの場合

複数のresourceを使いたい場合はuseをchainできます。

kotlin
try {
    Files.newOutputStream(path).use { ost ->
        Files.newInputStream(path).use { inst ->
            FileCopyUtils.copy(inst, ost)
        }
    }
} catch (e: Exception) {
    e.printStackTrace()
}

あまりchainしすぎるとネストが深くなるのが玉に瑕。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

はじめてのPlay Framework個人的メモ

Play Framework

よく使うもの

  • ソースファイルの置き場所 app
  • ビルドのためのスクリプトファイル sbt.bat
  • 設定ファイル置き場 conf
  • 全体のレイアウトを記述するファイルや画像などのリソースを置くフォルダ public
  • ビルド生成物が置かれるフォルダ target

appフォルダ

  • controllers ロジック
  • views HTML (Scalaのコードを埋め込んだ.scala.htmlという拡張子のファイル
  • モデルの定義もここに置く
  • ここに作るディレクトリは、フォルダではなくパッケージになる

Welcome to Play! が表示される仕組み

routesというファイルでルーティング設定

(クライアントからサーバに送る要求の種類とURLの組み合わせを、プラグラムのメソッドに結びつける)

GETメソッドでルート(デフォルトではlocalhost:9000)にアクセスすると、
app/controllersフォルダにあるHomeControllerクラスのindexメソッドが呼ばれる

conf/routes
GET     /                           controllers.HomeController.index

app/views/index.scala.html
@()

@main("Welcome to Play") {
  <h1>Welcome to Play!</h1>
  }

indexメソッドによって、テンプレートindexを呼び出す
main関数を実行。
(引数として、

title:Stringである"Welcome to Play
content:Htmlである<h1>Welcome to Play!
を渡している)
app/views/main.scala.html
 *@
@(title: String)(content: Html)

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
    </head>
    <body>

        @content

      <script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script>
    </body>
</html>

テンプレートindexによって、さらにmainを呼び出す
渡されてきた変数をHtmlに埋め込むには、@変数名とする。

リンクの貼り方

routesに記載された情報を利用する

routes
GET     /                           controllers.HomeController.index

GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

GET     /viewtest                   controllers.ViewTestController.index   #ここへのリンクを貼りたい

html内にて、

<a href="@routes.ViewTestController.index">view test</a>

のようにする。

注意点

  • ""で囲んでも、Twirlテンプレートとしてちゃんと動いてくれる
  • routes内ではcontrollers.~~となっているが、リンクを貼る際はroutes.~~に変えること

テンプレートへの変数の渡し方

こんな感じでテンプレートがあるとする。

viewtest_index.scala.html
@(title: String="自分で作ったファイル")

@viewtest_main("自分で作ったファイル"){
    <h1>@(title+"です")</h1>
}

titleという変数を受け取れるようしているが、初期値が設定してあるのでcontrollerでは

package controllers

import javax.inject._
import play.api._
import play.api.mvc._

@Singleton // 「シングルトン」の指定。「このクラスからは、たったひとつのオブジェクトしか作ってはいけない」という指示
class ViewTestController @Inject()(cc: ControllerComponents)
  extends AbstractController(cc) { // @Inject 「ccは、フレームワークで作る」というフレームワーク内部への指示

  def index() = Action { implicit request: Request[AnyContent] =>
    Ok(views.html.viewtest_index())
  }
}

この記述でOK。

しかし

@(title: String="自分で作ったファイル")(rnum: Int = 1)

@viewtest_main("自分で作ったファイル"){
    <h1>@(title+"です")</h1>
    <p>末尾が @rnum の方に大チャンス!!</p>

このように、テンプレートに変数を二つ定義しており、かつ初期値を持っている場合は、コントローラにて、
二つの変数どちらにも値を渡さず、初期値のままにする ということを伝えなければいけません。
その際は、
Ok(views.html.viewtest_index())
ではなく、(エラーが起きる)
Ok(views.html.viewtest_index()())
このように、メソッドの呼び出しにおいて()を二つ、(変数の数分)記述してプログラムに意図を伝えなければいけない。

テンプレート最上段の、@(title: String="自分で作ったファイル")(rnum: Int = 1)に、
コントローラのviews.html.viewtest_index()()が対応している形ですね。

そして、初期値を使わずに、コントローラから変数の値を指定する場合にも、変数の数だけ()を二つ並べます。

Ok(views.html.viewtest_index("コントローラから渡したtitle")(5))

また、テンプレート側で、変数の受け取り方を
@(title: String="自分で作ったファイル", rnum: Int = 1)
このように一つの()の中にカンマ区切りで納めると、渡し方のほうも、
Ok(views.html.viewtest_index("コントローラから渡したtitle", 5)
このように「普通の関数みたいな書き方」になります。

状況に応じて使い分けが必要
()を並べる方法は
* 渡す値が関数オブジェクトやHTMLブロックの際に見やすい
* 「変数を渡さない」という記述を、()を書くだけで簡単にできる
その反面、
* 引数が多くなった時にコンパイルに時間がかかる

という特徴があるため。

TwirlでのFor文の書き方

@(title: String= "for loopの練習", topics: Array[String])

<ul>
    @for(topic <- topics) {
        <li>@topic</li>
    }

</ul>

@の場所がちょっとややこしいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Color Map

Goal

Test OpenCV Color Map.

OpenCV_Apply_Color_Map.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_Apply_Color_Map {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private JFrame frmjavaSwing;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Apply_Color_Map window = new OpenCV_Apply_Color_Map();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_Apply_Color_Map() {
        initialize();
        System.out.println( "Imgproc.COLORMAP_AUTUMN="+Imgproc.COLORMAP_AUTUMN);
        System.out.println( "Imgproc.COLORMAP_BONE="+Imgproc.COLORMAP_BONE);
        System.out.println( "Imgproc.COLORMAP_COOL="+Imgproc.COLORMAP_COOL);
        System.out.println( "Imgproc.COLORMAP_HOT="+Imgproc.COLORMAP_HOT);
        System.out.println( "Imgproc.COLORMAP_HSV="+Imgproc.COLORMAP_HSV);
        System.out.println( "Imgproc.COLORMAP_JET="+Imgproc.COLORMAP_JET);
        System.out.println( "Imgproc.COLORMAP_OCEAN="+Imgproc.COLORMAP_OCEAN);
        System.out.println( "Imgproc.COLORMAP_PARULA="+Imgproc.COLORMAP_PARULA);
        System.out.println( "Imgproc.COLORMAP_PINK="+Imgproc.COLORMAP_PINK);
        System.out.println( "Imgproc.COLORMAP_RAINBOW="+Imgproc.COLORMAP_RAINBOW);
        System.out.println( "Imgproc.COLORMAP_SPRING="+Imgproc.COLORMAP_SPRING);
        System.out.println( "Imgproc.COLORMAP_SUMMER="+Imgproc.COLORMAP_SUMMER);
        System.out.println( "Imgproc.COLORMAP_WINTER="+ Imgproc.COLORMAP_WINTER);
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread(
                "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg", Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);

        //BufferedImage image=matToBufferedImage(applyColorMap(source,alpha));

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("讀取影像至Java Swing視窗");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showAlphaValue = new JLabel("2");
        showAlphaValue.setBounds(311, 20, 46, 15);
        frmjavaSwing.getContentPane().add(showAlphaValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 438, 438);
        //lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_alpha = new JSlider();
        slider_alpha.setMaximum(12);
        slider_alpha.setValue(2);
        slider_alpha.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showAlphaValue.setText(slider_alpha.getValue()+"");
                BufferedImage newImage=matToBufferedImage(applyColorMap(source,slider_alpha.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_alpha.setBounds(101, 10, 200, 25);
        frmjavaSwing.getContentPane().add(slider_alpha);

        JLabel lblAlpha = new JLabel("ColorMap");

        lblAlpha.setBounds(10, 20, 92, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

    }
    public Mat applyColorMap(Mat source,int colormap){

        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Imgproc.applyColorMap(source, destination, colormap);

        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_color_map.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV pyrMeanShift Filter

Goal

Test OpenCV pyrMeanShift filter.

OpenCV_pyrMeanShiftFiltering.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.TermCriteria;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_pyrMeanShiftFiltering {

    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmjavaSwing;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_pyrMeanShiftFiltering window = new OpenCV_pyrMeanShiftFiltering();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_pyrMeanShiftFiltering() {
        initialize();

    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv ªoµe³B²z½m²ß");
        frmjavaSwing.setBounds(100, 100, 565, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showSpValue = new JLabel("17");
        showSpValue.setBounds(142, 20, 46, 15);
        frmjavaSwing.getContentPane().add(showSpValue);

        final JSlider slider_method = new JSlider();
        slider_method.setMinimum(1);
        slider_method.setMaximum(30);
        slider_method.setValue(17);

        slider_method.setBounds(26, 10, 106, 25);
        frmjavaSwing.getContentPane().add(slider_method);

        JLabel lblAlpha = new JLabel("SP");
        lblAlpha.setBounds(10, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        final JLabel lblNewLabel_2 = new JLabel("");
        lblNewLabel_2.setBounds(10, 38, 517, 468);
        frmjavaSwing.getContentPane().add(lblNewLabel_2);

        JLabel lblSr = new JLabel("SR");
        lblSr.setBounds(176, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblSr);

        final JSlider slider = new JSlider();

        slider.setValue(30);
        slider.setMinimum(1);
        slider.setMaximum(50);
        slider.setBounds(199, 10, 112, 25);
        frmjavaSwing.getContentPane().add(slider);

        final JLabel showSrValue = new JLabel("30");
        showSrValue.setBounds(310, 20, 46, 15);
        frmjavaSwing.getContentPane().add(showSrValue);

        JLabel lblMaxlevel = new JLabel("maxLevel");
        lblMaxlevel.setBounds(342, 20, 65, 15);
        frmjavaSwing.getContentPane().add(lblMaxlevel);

        final JSlider slider_maxLevel = new JSlider();

        slider_maxLevel.setValue(1);
        slider_maxLevel.setMinimum(1);
        slider_maxLevel.setMaximum(10);
        slider_maxLevel.setBounds(404, 10, 106, 25);
        frmjavaSwing.getContentPane().add(slider_maxLevel);

        final JLabel labelMaxLevel = new JLabel("1");
        labelMaxLevel.setBounds(511, 20, 46, 15);
        frmjavaSwing.getContentPane().add(labelMaxLevel);

        slider_method.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showSpValue.setText(slider_method.getValue()+"");

                BufferedImage newImage=matToBufferedImage(pyrMeanShiftFiltering(slider_method.getValue(),slider.getValue(),slider_maxLevel.getValue()));
                lblNewLabel_2.setIcon(new ImageIcon(newImage));
            }
        });

        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showSrValue.setText(slider.getValue()+"");
                BufferedImage newImage=matToBufferedImage(pyrMeanShiftFiltering(slider_method.getValue(),slider.getValue(),slider_maxLevel.getValue()));
                lblNewLabel_2.setIcon(new ImageIcon(newImage));
            }
        });
        slider_maxLevel.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                labelMaxLevel.setText(slider_maxLevel.getValue()+"");
                BufferedImage newImage=matToBufferedImage(pyrMeanShiftFiltering(slider_method.getValue(),slider.getValue(),slider_maxLevel.getValue()));
                lblNewLabel_2.setIcon(new ImageIcon(newImage));
            }
        });
    }
    public Mat pyrMeanShiftFiltering(int sp,int sr,int maxLevel){
        Mat source2 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\clean.jpg");
        Mat output=new Mat();
        Imgproc.pyrMeanShiftFiltering(source2, output, sp, sr,maxLevel, new TermCriteria(TermCriteria.MAX_ITER| TermCriteria.EPS,50,0.001));

        return output;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_pyr_mean_shift_filter.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】オブジェクトのListについて、nullを考慮しつつ複数キーでソートする

案外詰まったので備忘用に残します。

やること

IDを3種類持つオブジェクトについて、以下のようにソートします。

  • id1 -> id2 -> id3」の順でそれぞれソートする
  • ソートは全て昇順(NaturalOrder)で行う
    • ただし、全てのソートでnullは最後とする

ソース

// import類
import static java.util.Comparator.comparing;
import static java.util.Comparator.naturalOrder;
import static java.util.Comparator.nullsLast;

/* 略 */

static void sortIdObject(List<IdObject> idObjects) {
  idObjects.sort(
      comparing(IdObject::getId1, nullsLast(naturalOrder()))
          .thenComparing(IdObject::getId2, nullsLast(naturalOrder()))
          .thenComparing(IdObject::getId3, nullsLast(naturalOrder()))
  );
}

解説

id1 -> id2 -> id3」の順でそれぞれソートする

この部分は、比較をcomparing(xxx).thenComparing(xxx).thenComparing...と繋いでいくことで実現できます。

ただし、全てのソートでnullは最後とする

今回はnullが最後なのでnullsLast([Comparator])で囲いました。
そもそも、用意されているcomparatornullを入れるとヌルポになるため、nullableな内容を比較する場合はnullsLastnullsFirstで囲ってやる必要があります。
また、nullsLast/Firstで囲ったとしても、compareIntなどのプリミティブ型に関する比較系はヌルポになるため注意が必要です。

ソートは全て昇順(NaturalOrder)で行う

ComparatornaturalOrder()を指定することで実現できます。
逆順だとreverseOrder()を指定することで実現できます。

補足

今回並び替えるオブジェクト

// ゲッターはLombokによる生成を想定
@Getter
public class IdObject {
  private Integer id1;
  private Integer id2;
  private Integer id3;
}

参考にさせていただいた内容

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Watershed

Goal

Test OpenCV Watershed.

OpenCV_Watershed.java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class OpenCV_Watershed {
    public static void main( String[] args )
    {
        try{
            System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
            Mat source = Imgcodecs.imread(
                    "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg",
                    Imgcodecs.CV_LOAD_IMAGE_COLOR);
            Mat gray=new Mat(source.rows(),source.cols(),CvType.CV_8UC1);
            Imgproc.cvtColor(source, gray, Imgproc.COLOR_BGR2GRAY);
            Mat binary=Mat.zeros(gray.rows(),gray.cols(),CvType.CV_8UC1);
            Imgproc.threshold(gray, binary, 100, 255, Imgproc.THRESH_BINARY);


            Mat fg=new Mat(source.size(),CvType.CV_8U);
            Imgproc.erode(binary, fg, new Mat(),new Point(-1,-1),2);

            Mat bg=new Mat(source.size(),CvType.CV_8U);
            Imgproc.dilate(binary, bg, new Mat(),new Point(-1,-1),3);
            Imgproc.threshold(bg,bg, 1, 128, Imgproc.THRESH_BINARY_INV);

            Mat markers=new Mat(binary.size(),CvType.CV_8U,new Scalar(0));
            Core.add(fg, bg, markers);


            Mat tmp=new Mat(binary.size(),CvType.CV_8U,new Scalar(0));
            Mat tmper=new Mat(binary.size(),CvType.CV_8U,new Scalar(0));
            Mat tmper1=new Mat(binary.size(),CvType.CV_8U,new Scalar(0));


            //Watershed
            markers.convertTo(tmper, CvType.CV_32S);
            Imgproc.watershed(source, tmper);
            tmper.convertTo(tmp, CvType.CV_8U);
            //markers.convertTo(tmp, CvType.CV_8U);
            tmper.convertTo(tmper1, CvType.CV_8U,255,255);
            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_watered.jpg", markers);
            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_watered1.jpg",tmp);
            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_watered2.jpg",tmper);
            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena_watered3.jpg",tmper1);

        }catch (Exception e) {
            System.out.println("error: " + e.getMessage());
        }
    }
}
Result

lena_watered.jpg
lena_watered1.jpg
lena_watered2.jpg
lena_watered3.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Expand

Goal

Test OpenCV expand.

OpenCV_Expand.java
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import java.awt.Canvas;

import javax.swing.ImageIcon;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JLabel;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.border.LineBorder;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

public class OpenCV_Expand {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmOpencv;
    private Mat src = Imgcodecs.imread(
            "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");
    private Color color;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Expand window = new OpenCV_Expand();
                    window.frmOpencv.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_Expand() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {



        final BufferedImage image=matToBufferedImage(src);

        frmOpencv = new JFrame();
        frmOpencv.setTitle("opencv 凸透鏡效果練習");
        frmOpencv.getContentPane().setBackground(Color.LIGHT_GRAY);
        frmOpencv.setBounds(100, 100, 547, 627);
        frmOpencv.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOpencv.getContentPane().setLayout(null);

        final JLabel lblShowXY = new JLabel("");
        lblShowXY.setBounds(405, 2, 124, 23);
        frmOpencv.getContentPane().add(lblShowXY);


        JPanel panel = new JPanel();

        final JLabel lblPaintLabel = new JLabel("");
        lblPaintLabel.setIcon(new ImageIcon(image));
        panel.add(lblPaintLabel);


        panel.setBounds(10, 64, 519, 519);
        frmOpencv.getContentPane().add(panel);

        JLabel lblNewLabel = new JLabel("強度");
        lblNewLabel.setBounds(10, 20, 58, 15);
        frmOpencv.getContentPane().add(lblNewLabel);

        final JSlider slider = new JSlider();
        slider.setMaximum(300);

        slider.setValue(30);
        slider.setMinimum(1);
        slider.setBounds(78, 10, 200, 25);
        frmOpencv.getContentPane().add(slider);

        final JLabel Label_scale = new JLabel("30");
        Label_scale.setBounds(298, 20, 46, 15);
        frmOpencv.getContentPane().add(Label_scale);

        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                Label_scale.setText(slider.getValue()+"");
            }
        });

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblShowXY.setText("X:"+arg0.getX()+",Y:"+arg0.getY());
                BufferedImage newImage=matToBufferedImage(expand(src,slider.getValue(),arg0.getX(),arg0.getY()) );
                lblPaintLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }

    public Mat expand(Mat source,int Scale,int PntX,int PntY){
        Point pt=new Point(PntX,PntY);
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        source.copyTo(destination);
        for (int y=0;y<source.height();y++){

            for(int x=0;x<source.width();x++){

                int dist=(int)getDistance(new Point(x,y),pt);
                if(dist<Scale){
                    int newX=(int) (((x-pt.x)*dist/Scale)+pt.x);
                    int newY=(int) (((y-pt.y)*dist/Scale)+pt.y);
                    double[] temp=source.get(newY,newX*2);
                    double[] temp1=source.get(newY,newX*2+1);
                    double[] temp2=source.get(newY,newX*2+2);

                    if (temp!=null){
                        destination.put(y,2*x,temp);
                    }
                    if (temp1!=null){
                        destination.put(y,2*x+1,temp1);
                    }
                    if (temp2!=null){
                        destination.put(y,2*x+2,temp2);
                    }
                }
            }
        }
        return destination;
    }
    public static double getDistance(Point a,Point b){
        return Math.sqrt(Math.pow(a.x-b.x, 2)+Math.pow(a.y-b.y, 2));
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}
Result

opencv_expand.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

リファクタリングのメモ(UI編)

ここは?

UIが絡んだコードを、後で見返しても再度理解しやすいように書き換える技を綴っています。
UI編でない方はこちら

UIの導入

UIを導入するとなるとビジネスロジックの他にUIに関連するコーディングが増えるので、一気に複雑性が増し、可読性や保守性の低下を招きうるケースが多くなります。
こちらで紹介しているコードを例にとり、そのコードにUIを導入するケースで考えてみます。

画面構成

想定する画面構成です。
その画面に設けるコンポーネントとその機能についても触れています。

  • メイン画面
    • 「生徒リスト」ボタン、「果物リスト」ボタン、「単位リスト」ボタン
      • それぞれ該当するリストを表示する。
  • 生徒リスト
    • 登録されている生徒の名前、好きな果物、その食べたい量が半角コンマ区切りで一覧表示される。
  • 果物リスト
    • 登録されている果物の名前、その単位が半角コンマ区切りで一覧表示される。
  • 単位リスト
    • 登録されている単位が一覧表示される。

プログラムを起動するとメイン画面が表示され、その画面からボタンを通じてユーザーが他の各リストを表示できる仕組みとします。

実際のビジュアルはこんな感じ。

とはいってもこのくらいは複雑に入らない人がざらでしょうね。
でも、要件が変われば最初は複雑ではなかったものでもいくらでも複雑になる可能性はありますので、なんどきも油断せず。

元となるソースコード

MainクラスをUI用に修正し、このクラスだけ抜粋したソースコードです。

public class Main extends JPanel {

  private Main() {
    super(new BorderLayout());
    JList<String> list = new JList<>();
    JPanel west = new JPanel() {{
      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
      setBorder(new EmptyBorder(5, 5, 5, 0));
      JButton student = new JButton("生徒リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(StudentConstants.class.getEnumConstants())
          .forEach(student -> model.addElement(student.getInfo()));
          list.setModel(model);
        });
      }};
      JButton fruit = new JButton("果物リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(FruitConstants.class.getEnumConstants())
          .forEach(fruit -> model.addElement(fruit.getInfo()));
          list.setModel(model);
        });
      }};
      JButton measureWord = new JButton("単位リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(MeasureWord.class.getDeclaredFields())
          .filter(f -> f.getType() == MeasureWord.class)
          .forEach(f -> {
            try {
              model.addElement(((MeasureWord) f.get(null)).name());
            } catch (Exception ex) {}
          });
          list.setModel(model);
        });
      }};
      add(student);
      add(fruit);
      add(measureWord);
    }};
    JPanel center = new JPanel() {{
      JScrollPane scrollPane = new JScrollPane(list);
      scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
      scrollPane.setPreferredSize(new Dimension(320, 240));
      add(scrollPane);
    }};
    add(west, BorderLayout.WEST);
    add(center, BorderLayout.CENTER);
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
        e.printStackTrace();
        Toolkit.getDefaultToolkit().beep();
      }
      new JFrame("テスト") {{
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
        add(new Main(), BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(null);
      }};
    });
  }
}

コンストラクタやmainメソッドにUIに対して処理を命令するビジネスロジックが大いに組み込まれています。
また似たような記述(繰り返し登場するアクションリスナーの記述)も見られます。
このままでは将来UIや機能の大幅な加筆修正をしなければならなくなった時に、Mainクラスが肥大化し神コードが誕生してしまうでしょう。

MVCの考え方を導入し、どのようにクラス抽出をすべきかを考えてみます。

つづく・・・

もくじに戻る

https://qiita.com/k73i55no5/items/9e0825cee4cc1cb078a6

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

リファクタリングのメモ(GUI編)

ここは?

GUIが絡んだコードを、後で見返しても再度理解しやすいように書き換える技を綴っています。
GUI編でない方はこちら

断り書き

GUI編でない方と同じです。

GUIの導入

GUIを導入するとなるとビジネスロジックの他にGUIに関連するコーディングが増えるので、一気に複雑性が増し、可読性や保守性の低下を招きうるケースが多くなります。
こちらで紹介しているコードを例にとり、そのコードにGUIを導入するケースで考えてみます。

画面構成

想定する画面構成です。
その画面に設けるコンポーネントとその機能についても触れています。

  • メイン画面
    • 「生徒リスト」ボタン、「果物リスト」ボタン、「単位リスト」ボタン
      • それぞれ該当するリストを表示する。
  • 生徒リスト
    • 登録されている生徒の名前、好きな果物、その食べたい量が半角コンマ区切りで一覧表示される。
  • 果物リスト
    • 登録されている果物の名前、その単位が半角コンマ区切りで一覧表示される。
  • 単位リスト
    • 登録されている単位が一覧表示される。

プログラムを起動するとメイン画面が表示され、その画面からボタンを通じてユーザーが他の各リストを表示できる仕組みとします。

実際のビジュアルはこんな感じ。

とはいってもこのくらいは複雑に入らない人がざらでしょうね。
でも、要件が変われば最初は複雑ではなかったものでもいくらでも複雑になる可能性はありますので、なんどきも油断せず。

元となるソースコード

MainクラスをGUI用に修正し、このクラスだけ抜粋したソースコードです。

public class Main extends JPanel {

  private Main() {
    super(new BorderLayout());
    JList<String> list = new JList<>();
    JPanel west = new JPanel() {{
      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
      setBorder(new EmptyBorder(5, 5, 5, 0));
      JButton student = new JButton("生徒リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(StudentConstants.class.getEnumConstants())
          .forEach(student -> model.addElement(student.getInfo()));
          list.setModel(model);
        });
      }};
      JButton fruit = new JButton("果物リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(FruitConstants.class.getEnumConstants())
          .forEach(fruit -> model.addElement(fruit.getInfo()));
          list.setModel(model);
        });
      }};
      JButton measureWord = new JButton("単位リスト") {{
        addActionListener(e -> {
          DefaultListModel<String> model = new DefaultListModel<>();
          Stream.of(MeasureWord.class.getDeclaredFields())
          .filter(f -> f.getType() == MeasureWord.class)
          .forEach(f -> {
            try {
              model.addElement(((MeasureWord) f.get(null)).name());
            } catch (Exception ex) {}
          });
          list.setModel(model);
        });
      }};
      add(student);
      add(fruit);
      add(measureWord);
    }};
    JPanel center = new JPanel() {{
      JScrollPane scrollPane = new JScrollPane(list);
      scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
      scrollPane.setPreferredSize(new Dimension(320, 240));
      add(scrollPane);
    }};
    add(west, BorderLayout.WEST);
    add(center, BorderLayout.CENTER);
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
        e.printStackTrace();
        Toolkit.getDefaultToolkit().beep();
      }
      new JFrame("テスト") {{
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
        add(new Main(), BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(null);
      }};
    });
  }
}

コンストラクタやmainメソッドにGUIに対して処理を命令するビジネスロジックが大いに組み込まれています。
また似たような記述(繰り返し登場するアクションリスナーの記述)も見られます。
このままでは将来GUIや機能の大幅な加筆修正をしなければならなくなった時に、Mainクラスが肥大化し神コードが誕生してしまうでしょう。

MVCの考え方を導入し、どのようにクラス抽出をすべきか考えてみます。

MVC

クラス抽出

まず、ビューに当てはまる要素を取り上げます。
今回の例で言えば「メイン画面」を構成するオブジェクト(フレーム、パネル)です。
くどくなりすぎない程度にビューとして抽出します。
またビューのコンストラクタは、UIの初期化に関する記述のみとし、ビジネスロジックは記述しないこととします。

「リストを入力に応じて切り替え表示させる」という一連のビジネスロジックは、モデルとして抽出します。
表示させるために必要なクラス群は同一パッケージ内にまとめ、モデルがビューに依存することのないようにします。

なお、サービスの実装やビューにはシングルトンパターンを導入します。
シングルトンは、それを導入したクラスから生成されたインスタンスを参照する際に、必ず同一のオブジェクトを返すことを保証してくれます。
そうすれば様々なクラスからGUIオブジェクトを参照した際に、実はそれが別のインスタンスで想定とは全然違うオブジェクトに処理を施してしまっていたなんていうミスを防いでくれます。

リファクタリング

リファクタリングの例です。

Mainクラス
final class Main extends JPanel {

  private Main() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
      e.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    MainFrame.getInstance().setVisible(true);
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> new Main());
  }
}

mainメソッドをもつクラスが大分スッキリしました(そのかわりクラス数とコーディング量は増えましたが)。
このクラスにはルックアンドフィールの初期化とフレーム(メイン画面)を表示させる処理のみの記述としています。

MainFrameクラス
public final class MainFrame extends JFrame {

  private MainFrame() {
    super("テスト");
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setResizable(false);
    add(MainPanel.getInstance(), BorderLayout.CENTER);
    pack();
    setLocationRelativeTo(null);
  }

  public static MainFrame getInstance() { return Holder.INSTANCE; }
  private static class Holder {
    static final MainFrame INSTANCE = new MainFrame();
  }
}

フレーム(メイン画面)を表示させるクラスです。
このクラスも、UIの初期化に関する記述のみとしています。
クラスごとに行うべき処理を区別し記述したことで、クラス毎にどんな役割を担っているのか大分理解しやすくなっているはずです。

MainPanelクラス
public final class MainPanel extends JPanel {

  enum Button {
    STUDENT("生徒リスト", mainService.showStudentList()),
    FRUIT("果物リスト", mainService.showFruitList()),
    MEASURE_WORD("単位リスト", mainService.showMeasureWordList()),;

    private String text;
    private ActionListener listener;

    private Button(String text, ActionListener listener) {
      this.text = text;
      this.listener = listener;
    }

    JButton get() {
      JButton button = new JButton(text);
      button.addActionListener(listener);
      return button;
    }
  }

  private static MainService mainService = MainServiceImpl.getInstance();

  private MainPanel() {
    super(new BorderLayout());
    JPanel west = new JPanel() {{
      setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
      setBorder(new EmptyBorder(5, 5, 5, 0));
      Stream.of(Button.class.getEnumConstants())
      .map(Button::get)
      .forEach(this::add);
    }};
    JPanel center = new JPanel() {{
      add(mainService.getJScrollPaneOfList());
    }};
    add(west, BorderLayout.WEST);
    add(center, BorderLayout.CENTER);
  }

  public static MainPanel getInstance() { return Holder.INSTANCE; }
  private static class Holder {
    static final MainPanel INSTANCE = new MainPanel();
  }
}

フレーム内部の構造を示すクラスです。
レイアウトの種類などはここでは触れません。

クラス中央付近にあるmainServiceインターフェースを利用して、モデルを参照します。
例えば各ボタンを表す列挙子の第二引数を見てみると、各リストを表示させるための処理をもたせたオブジェクト(アクションリスナー)を参照するためにインターフェースを利用しています。
インターフェースを利用することにより、直接モデルがビューに依存することなく、モデルの実装を隠蔽(カプセル化)させることができます。
後でサービスを加筆修正したくなっても、その実装の機能を利用するためのメソッドを加筆修正した後、実装を加筆修正すれば良いだけで済みます。

今回は各ボタンをパネルクラスの中に列挙型として含ませていますが、コンポーネントの数が増えるような想定であれば、クラスから独立させて管理したほうが良いでしょう。

MainServiceの実装クラス
public final class MainServiceImpl implements MainService {

  private static JList<String> list = new JList<>();
  private static DefaultListModel<String> model;

  private MainServiceImpl() {}

  @Override public JScrollPane getJScrollPaneOfList() {
    JScrollPane scrollPane = new JScrollPane(list);
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setPreferredSize(new Dimension(320, 240));
    return scrollPane;
  }

  @Override public ActionListener showStudentList() {
    return e -> {
      model = new DefaultListModel<>();
      Stream.of(StudentConstants.class.getEnumConstants())
      .forEach(student -> model.addElement(student.getInfo()));
      list.setModel(model);
    };
  }

  @Override public ActionListener showFruitList() {
    return e -> {
      model = new DefaultListModel<>();
      Stream.of(FruitConstants.class.getEnumConstants())
      .forEach(fruit -> model.addElement(fruit.getInfo()));
      list.setModel(model);
    };
  }

  @Override public ActionListener showMeasureWordList() {
    return e -> {
      model = new DefaultListModel<>();
      Stream.of(MeasureWord.class.getDeclaredFields())
      .filter(f -> f.getType() == MeasureWord.class)
      .forEach(f -> {
        try {
          model.addElement(((MeasureWord) f.get(null)).name());
        } catch (Exception ex) {
          // 本来は省略すべきでないが、ここでは省略。
        }
      });
      list.setModel(model);
    };
  }

  public static MainServiceImpl getInstance() { return Holder.INSTANCE; }
  private static class Holder {
    static final MainServiceImpl INSTANCE = new MainServiceImpl();
  }
}

そして、モデルにあたるMainServiceの実装クラスです。
このクラスには、ボタン入力によりリストを表示させる機能、ビューにスクロールバー付きのリストを返す機能を設けています。
ビジネスロジックの達成に必要な他のオブジェクト(生徒クラス、果物クラスなど)はすべてこのクラスが存在するパッケージに含ませています。
ビューからは先程述べたインターフェースを利用して、このクラスに記述するビジネスロジックの恩恵を受けることができます。

詳しいパッケージングや全体のコードについては、こちらをご参照ください。
https://github.com/k73i55no5/Samples/tree/7389eba/Refactorers/student190520/0.1/src

もくじに戻る

https://qiita.com/k73i55no5/items/9e0825cee4cc1cb078a6

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Spot

Goal

Test OpenCV spot.

OpenCV_Spot.java
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import java.awt.Canvas;

import javax.swing.ImageIcon;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JLabel;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.border.LineBorder;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

public class OpenCV_Spot {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmOpencv;
    private Mat sourceMat=Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");
    private Color color;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Spot window = new OpenCV_Spot();
                    window.frmOpencv.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_Spot() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {



        final BufferedImage image=matToBufferedImage(sourceMat);

        frmOpencv = new JFrame();
        frmOpencv.setTitle("opencv 聚光燈效果練習");
        frmOpencv.getContentPane().setBackground(Color.LIGHT_GRAY);
        frmOpencv.setBounds(100, 100, 547, 627);
        frmOpencv.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOpencv.getContentPane().setLayout(null);

        final JLabel lblShowXY = new JLabel("");
        lblShowXY.setBounds(405, 2, 124, 23);
        frmOpencv.getContentPane().add(lblShowXY);


        JPanel panel = new JPanel();

        final JLabel lblPaintLabel = new JLabel("");
        lblPaintLabel.setIcon(new ImageIcon(image));
        panel.add(lblPaintLabel);


        panel.setBounds(10, 64, 519, 519);
        frmOpencv.getContentPane().add(panel);

        JLabel lblNewLabel = new JLabel("聚光強度");
        lblNewLabel.setBounds(10, 20, 58, 15);
        frmOpencv.getContentPane().add(lblNewLabel);

        final JSlider slider = new JSlider();

        slider.setValue(30);
        slider.setMinimum(1);
        slider.setBounds(78, 10, 200, 25);
        frmOpencv.getContentPane().add(slider);

        final JLabel Label_scale = new JLabel("30");
        Label_scale.setBounds(298, 20, 46, 15);
        frmOpencv.getContentPane().add(Label_scale);

        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                Label_scale.setText(slider.getValue()+"");
            }
        });

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblShowXY.setText("X:"+arg0.getX()+",Y:"+arg0.getY());
                BufferedImage newImage=matToBufferedImage(spot(sourceMat,slider.getValue(),arg0.getX(),arg0.getY()) );
                lblPaintLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }

    public Mat spot(Mat source,int Scale,int PntX,int PntY){
        double scale=0-Scale;
        Point pt=new Point(PntX,PntY);
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        for (int j=0;j<source.rows();j++){
            for(int i=0;i<source.cols();i++){
                double[] temp=source.get(j,i);
                double dx=((j-pt.x)/pt.x);
                double dy=((i-pt.y)/pt.y);
                double weight=Math.exp((dx*dx+dy*dy)*scale);
                temp[0]=Math.round(temp[0]*weight);
                temp[1]=Math.round(temp[1]*weight);
                temp[2]=Math.round(temp[2]*weight);
                destination.put(j, i, temp);
            }
        }
        return destination;
    }


    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}
Result

opencv_spot.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Grab Cut

Goal

Test OpenCV grab cut.

OpenCV_GrabCut.java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class OpenCV_GrabCut {

    public static void main( String[] args )
    {
        try{
            System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
            Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg",
                    Imgcodecs.CV_LOAD_IMAGE_COLOR);
            bgSubtracting(source);
        }catch (Exception e) {
            System.out.println("error: " + e.getMessage());
        }
    }

    private static void bgSubtracting(Mat img) {
        Mat firstMask = new Mat();
        Mat bgModel = new Mat();//grabCut內部運算使用
        Mat fgModel = new Mat();//grabCut內部運算使用
        Mat mask;
        Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0));
        //定義矩形
        Rect rect = new Rect(0, 0,150,200);

        ///執行grabCut處理(分割)行
        Imgproc.grabCut(img, firstMask, rect, bgModel, fgModel, 1, 0 );


        //得到前景
        Core.compare(firstMask, source, firstMask, Core.CMP_EQ);
        //生成輸出圖像
        Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255,
                255, 255));
        //複製前景數據,符合挖出的區域
        img.copyTo(foreground, firstMask);

        mask = new Mat(foreground.size(), CvType.CV_8UC1, new Scalar(255, 255, 255));

        Imgproc.cvtColor(foreground, mask, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(mask, mask, 254, 255, Imgproc.THRESH_BINARY_INV);
        //挖出後的替代color
        Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(255.0));

        img.setTo(vals, mask);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\grab_cut.jpg", img);
    }

}
Result

grab_cut.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Canny

Goal

Test OpenCV canny.

OpenCV_Canny.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_Canny {
    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =2;
    double beta = 50;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Canny window = new OpenCV_Canny();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public OpenCV_Canny() {
        initialize();

    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv CannyÃä½tÀË´ú½m²ß");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showKsizeValue = new JLabel("0");
        showKsizeValue.setBounds(235, 10, 31, 15);
        frmjavaSwing.getContentPane().add(showKsizeValue);

        final JLabel showShapeValue = new JLabel("0");
        showShapeValue.setBounds(466, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showShapeValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(8, 45, 438, 438);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_th2 = new JSlider();
        slider_th2.setValue(0);
        slider_th2.setMaximum(900);
        slider_th2.setBounds(330, 10, 137, 25);
        frmjavaSwing.getContentPane().add(slider_th2);

        final JSlider slider_th1 = new JSlider();
        slider_th1.setMaximum(900);
        slider_th1.setValue(0);
        slider_th1.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showKsizeValue.setText(slider_th1.getValue()+"");
                BufferedImage newImage=matToBufferedImage(Canny(source,slider_th1.getValue(),slider_th2.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_th1.setBounds(72, 10, 164, 25);
        frmjavaSwing.getContentPane().add(slider_th1);

        JLabel lblAlpha = new JLabel("threshold1");
        lblAlpha.setBounds(8, 10, 64, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBeta = new JLabel("threshold2");
        lblBeta.setBounds(264, 10, 64, 15);
        frmjavaSwing.getContentPane().add(lblBeta);


        slider_th2.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showShapeValue.setText(slider_th2.getValue()+"");
                BufferedImage newImage=matToBufferedImage(Canny(source,slider_th1.getValue(),slider_th2.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }

    public Mat Canny(Mat source, double threshold1, double threshold2){
        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Imgproc.Canny(source, destination, threshold1, threshold2);
        return destination;
    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_canny.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Dilate

Goal

Test OpenCV dilate.

OpenCV_Dilate.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_Dilate {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =2;
    double beta = 50;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Dilate window = new OpenCV_Dilate();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_Dilate() {
        initialize();
        System.out.println("Imgproc.MORPH_RECT="+Imgproc.MORPH_RECT);
        System.out.println("Imgproc.MORPH_ELLIPSE="+Imgproc.MORPH_ELLIPSE);
        System.out.println("Imgproc.MORPH_CROSS="+ Imgproc.MORPH_CROSS);

    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv Dilate(膨脹)處理練習");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showKsizeValue = new JLabel("0");
        showKsizeValue.setBounds(250, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showKsizeValue);

        final JLabel showShapeValue = new JLabel("0");
        showShapeValue.setBounds(402, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showShapeValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 438, 438);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_shape = new JSlider();
        slider_shape.setValue(0);
        slider_shape.setMaximum(2);
        slider_shape.setBounds(326, 10, 75, 25);
        frmjavaSwing.getContentPane().add(slider_shape);

        final JSlider slider_ksize = new JSlider();
        slider_ksize.setMaximum(50);
        slider_ksize.setValue(0);
        slider_ksize.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showKsizeValue.setText(slider_ksize.getValue()+"");
                BufferedImage newImage=matToBufferedImage(dilate(source,slider_ksize.getValue(),slider_shape.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_ksize.setBounds(47, 10, 200, 25);
        frmjavaSwing.getContentPane().add(slider_ksize);

        JLabel lblAlpha = new JLabel("Ksize");
        lblAlpha.setBounds(10, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBeta = new JLabel("shape");
        lblBeta.setBounds(283, 10, 46, 15);
        frmjavaSwing.getContentPane().add(lblBeta);


        slider_shape.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showShapeValue.setText(slider_shape.getValue()+"");
                BufferedImage newImage=matToBufferedImage(dilate(source,slider_ksize.getValue(),slider_shape.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }

    public Mat dilate(Mat source,int ksize,int shape){

        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Mat element = Imgproc.getStructuringElement(shape,new Size(2*ksize + 1, 2*ksize+1));
        Imgproc.dilate(source, destination, element);

        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}

Result

opencv_dilate.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Erode

Goal

Test OpenCV Erode.

OpenCV_Erode.java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class OpenCV_Erode {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;
    double alpha =2;
    double beta = 50;

    /**
        * Launch the application.
        */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try{
                    OpenCV_Erode window = new OpenCV_Erode();
                    window.frmjavaSwing.setVisible(true);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_Erode() {
        initialize();
        System.out.println("Imgproc.MORPH_RECT="+Imgproc.MORPH_RECT);
        System.out.println("Imgproc.MORPH_ELLIPSE="+ Imgproc.MORPH_ELLIPSE);
        System.out.println("Imgproc.MORPH_CROSS="+Imgproc.MORPH_CROSS);

    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv Erode(»G»k)³B²z½m²ß");
        frmjavaSwing.setBounds(100, 100, 520, 550);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel showKsizeValue = new JLabel("0");
        showKsizeValue.setBounds(250, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showKsizeValue);

        final JLabel showShapeValue = new JLabel("0");
        showShapeValue.setBounds(402, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showShapeValue);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(10, 68, 438, 438);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        final JSlider slider_shape = new JSlider();
        slider_shape.setValue(0);
        slider_shape.setMaximum(2);
        slider_shape.setBounds(326, 10, 75, 25);
        frmjavaSwing.getContentPane().add(slider_shape);

        final JSlider slider_ksize = new JSlider();
        slider_ksize.setMaximum(50);
        slider_ksize.setValue(0);
        slider_ksize.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                //System.out.println(slider_alpha.getValue());
                showKsizeValue.setText(slider_ksize.getValue()+"");
                BufferedImage newImage=matToBufferedImage(erode(source,slider_ksize.getValue(),slider_shape.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        slider_ksize.setBounds(47, 10, 200, 25);
        frmjavaSwing.getContentPane().add(slider_ksize);

        JLabel lblAlpha = new JLabel("Ksize");
        lblAlpha.setBounds(10, 20, 46, 15);
        frmjavaSwing.getContentPane().add(lblAlpha);

        JLabel lblBeta = new JLabel("shape");
        lblBeta.setBounds(283, 10, 46, 15);
        frmjavaSwing.getContentPane().add(lblBeta);


        slider_shape.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showShapeValue.setText(slider_shape.getValue()+"");
                BufferedImage newImage=matToBufferedImage(erode(source,slider_ksize.getValue(),slider_shape.getValue()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
    }
    public Mat erode(Mat source,int ksize,int shape){

        Mat destination=new Mat(source.rows(),source.cols(),source.type());
        Mat element = Imgproc.getStructuringElement(shape,new Size(2*ksize + 1, 2*ksize+1));
        Imgproc.erode(source, destination, element);

        return destination;

    }

    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

}
Result

opencv_erode.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

java側linuxのzipコマンドで圧縮

java側linuxのzipコマンドを呼び出したい場合、ProcessBuilderを利用できます。
例1:
全部ディレクトリ保持の場合、
List commandList = new ArrayList();
commandList.add("-r");
ProcessBuilder pb =new ProcessBuilder(commandList);

例2:
ディレクトリ保持しない場合、(同じファイル名あれば、エラー)
List commandList = new ArrayList();
commandList.add("-j");
ProcessBuilder pb =new ProcessBuilder(commandList);
LINUXのzipコマンド一覧
-f freshen: only changed files
-u update: only changed or new files
-d delete entries in zipfile
-m move into zipfile (delete OS files)
-r recurse into directories
-j junk (don't record) directory names
-0 store only
-l convert LF to CR LF (-ll CR LF to LF)
-1 compress faster
-9 compress better
-q quiet operation
-v verbose operation/print version info
-c add one-line comments
-z add zipfile comment
-@ read names from stdin
-o make zipfile as old as latest entry
-x exclude the following names
-i include only the following names
-F fix zipfile (-FF try harder)
-D do not add directory entries
-A adjust self-extracting exe
-J junk zipfile prefix (unzipsfx)
-T test zipfile integrity
-X eXclude eXtra file attributes
-y store symbolic links as the link instead of the referenced file
-e encrypt
-n don't compress these suffixes

例3下記の場合はどうする?
フォルダの形式:/home/AB/CD/+各種ファイルとサブフォルダ
入力パース
/home/AB/CD/
圧縮後(/home/AB/CD/含まない)
各種ファイルとサブフォルダ.zip
試して、下記のコマンドはいいです。

pb = new ProcessBuilder("sh", "-c", “zip -r test.zip ./*”)).directory(new File("/home/AB/CD/"));
同じく書きの書き方でもいいです。
pb = new ProcessBuilder("/bin/sh", "-c", “zip -r test.zip ./*”)).directory(new File("/home/AB/CD/"));
pb = new ProcessBuilder("/bin/bash", "-c", “zip -r test.zip ./*”)).directory(new File("/home/AB/CD/"));

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Emboss For Rectangle

Goal

Test OpenCV emboss for rectangle.

OpenCV_EmbossForRectangle.java
import java.awt.EventQueue;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import org.opencv.core.MatOfPoint;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class OpenCV_EmbossForRectangle {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmjavaSwing;

    public int srcX=0;
    public int srcY=0;

    public int secondX=0;
    public int secondY=0;

    public Point innerP1;
    public Point innerP2;

    public Mat matWantToSave;

    public Mat EmbossArea1;
    public Mat EmbossArea2;
    public Mat EmbossArea3;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_EmbossForRectangle window = new OpenCV_EmbossForRectangle();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_EmbossForRectangle() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread(
                "D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0836.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("擷取ROI製作立體浮雕製作練習");
        frmjavaSwing.setBounds(100, 100, 990, 395);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblLocation = new JLabel("");
        lblLocation.setBounds(10, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation);

        final JLabel lblLocation2 = new JLabel("");
        lblLocation2.setBounds(158, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation2);

        JPanel panel = new JPanel();
        panel.setBounds(10, 45, 473, 301);
        frmjavaSwing.getContentPane().add(panel);

        final JLabel lblNewLabel = new JLabel("");
        panel.add(lblNewLabel);

        //監聽mouse事件,點擊第2個的點
        lblNewLabel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent arg0) {
                lblLocation2.setText("X:"+arg0.getX()+",Y:"+arg0.getY());

                setSecondX(arg0.getX());
                setSecondY(arg0.getY());

                BufferedImage newImage=matToBufferedImage(paintRectangle(arg0.getX(),arg0.getY()));
                lblNewLabel.setIcon(new ImageIcon(newImage));


            }
        });

        final JLabel lblRoi = new JLabel("");
        lblRoi.setBounds(494, 45, 478, 306);
        frmjavaSwing.getContentPane().add(lblRoi);


        lblNewLabel.setIcon(new ImageIcon(image));

        JButton btnNewButton = new JButton("擷取ROI並且立體化");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                getRoiAndEmboss();
                if (getEmbossArea1()!=null){

                    Mat source1 = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0836.jpg");
                    //再把小圖copy到大圖
                    //Area1
                    Mat embossArea1=getEmbossArea1();//get浮雕Area1區塊

                    //取Area1及Area3的ROI區域
                    Rect roi=new Rect(Math.min(getSrcX(),getSecondX()),Math.min(getSrcY(),getSecondY()),Math.abs(getSecondX()-getSrcX()),Math.abs(getSecondY()-getSrcY()));//不能比原圖大,及小

                    //貼至source1
                    Mat destinationROI = source1.submat( roi );
                    embossArea1.copyTo( destinationROI , embossArea1);
                    //Area2
                    Mat embossArea2=getEmbossArea2();//get浮雕Area2區塊
                    //取Area2及Area3的ROI區域
                    Rect tempInner=new Rect(getInnerP1(),getInnerP2());
                    //貼至source1
                    Mat innerMat=source1.submat( tempInner );
                    embossArea2.copyTo( innerMat , embossArea2);

                    //Area3
                    Mat embossArea3=getEmbossArea3();//get浮雕Area3區塊
                    //貼至source1
                    embossArea3.copyTo( destinationROI , embossArea3);

                    BufferedImage image=matToBufferedImage(source1);
                    lblRoi.setText("");
                    lblRoi.setIcon(new ImageIcon(image));

                }else{
                    lblRoi.setText("未規劃ROI區塊!");
                }

            }
        });
        btnNewButton.setBounds(278, 10, 150, 25);
        frmjavaSwing.getContentPane().add(btnNewButton);


        //監聽mouse事件,點擊第1個的點
        lblNewLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblLocation2.setText("");
                lblLocation.setText("初始點:X:"+arg0.getX()+",Y:"+arg0.getY());
                setSrcX(arg0.getX());
                setSrcY(arg0.getY());
                BufferedImage newImage=matToBufferedImage(paintPoint(arg0.getX(),arg0.getY()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });



    }
    //繪圖於第1個的點
    public Mat paintPoint(int x,int y){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0836.jpg");
        Imgproc.circle(src, new Point(x,y), 2, new Scalar(0,55,255),2);
        return src;

    }
    //繪ROI區,欲立體化 or浮雕化
    public Mat paintRectangle(int x,int y){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0836.jpg");
        Point srcPoint=new Point(getSrcX(),getSrcY());
        Imgproc.rectangle(src, srcPoint, new Point(x,y), new Scalar(0,0,255),2);
        setSecondX(x);
        setSecondY(y);
        return src;

    }
    //處理原圖ROI區變立體化 or浮雕化
    public void getRoiAndEmboss(){
        Mat RoiMat;
        Mat MaskTemplate = null;
        Mat dst = new Mat();
        if(getSecondX()>0 && getSecondY()>0){
            Mat source=
                    Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0836.jpg");
            Rect roi=new Rect(new Point(getSrcX(),getSrcY()),new Point(getSecondX(),getSecondY()));

            RoiMat=source.submat(roi);
            // source.

            //area1-start,找出area1的左上斜邊,右上斜,右下斜邊
            //斜角是45度,算出徑度
            double angleRad = 45*Math.PI / 180.0;   // convert angle to radians
            //先定義與ROI同size,全白單通道模板
            MaskTemplate=new Mat(RoiMat.size(),CvType.CV_8UC1,new Scalar(0));

            int length = 25;//立體化 or浮雕化的厚度
            Point direction = new Point(length * Math.cos(angleRad), length * Math.sin(angleRad)); // calculate direction

            //多邊形fillPoly所需資料結構
            List<MatOfPoint> allMatOfPoint=new ArrayList<MatOfPoint>();
            MatOfPoint mop1=new MatOfPoint();
            List<Point> allPoint1=new ArrayList<Point>();

            //area1的6個點,要循序
            allPoint1.add(new Point(0,0));//p1
            allPoint1.add(new Point(0 +direction.x*0.5,0 +direction.y*0.5));//p2
            allPoint1.add(new Point(RoiMat.width()-direction.x*0.5,0 +direction.y*0.5));//p3
            allPoint1.add(new Point(RoiMat.width()-direction.x*0.5,RoiMat.height()-direction.y*0.5));//p4
            allPoint1.add(new Point(RoiMat.width(),RoiMat.height()));//p5
            allPoint1.add(new Point(RoiMat.width(),0));//p6
            mop1.fromList(allPoint1);
            allMatOfPoint.add(mop1);
            Imgproc.fillPoly(MaskTemplate, allMatOfPoint,  new Scalar(255,255,255));//完成填充,area1為白色(255,255,255)

            //取到多邊形area1的mat
            Core.bitwise_and(RoiMat, RoiMat, dst,MaskTemplate);
            //area1明亮化處理
            dst.convertTo(dst, -1, 2, 50);
            //設為global value,在被貼處還需用到
            setEmbossArea1(dst);
            //area1-end

            //area2-start,找出area2的inner矩形部份
            Mat dst2 = new Mat();

            //inner矩形部份變成ROI
            Rect rectDst2=new Rect(new Point(0 +direction.x*0.5,0 +direction.y*0.5),new Point(RoiMat.width()-direction.x*0.5,RoiMat.height()-direction.y*0.5));
            //設為global value,在被貼處還需用到
            setInnerP1(getSrcX()+(int)direction.x*0.5,0 +getSrcY()+(int)direction.y*0.5);
            setInnerP2(getSrcX()+RoiMat.width()-direction.x*0.5,getSrcY()+RoiMat.height()-direction.y*0.5);
            //取到area2的inner矩形部份,且為Mat
            dst2=RoiMat.submat(rectDst2);
            //設為global value,在被貼處還需用到
            setEmbossArea2(dst2);


            //area3-start,找出area1的左上斜邊,左下斜,右下斜邊
            Mat dst3 = new Mat();
            RoiMat=source.submat(roi);
            //先定義與ROI同size,全白單通道模板
            MaskTemplate=new Mat(RoiMat.size(),CvType.CV_8UC1,new Scalar(0));

            //多邊形fillPoly所需資料結構
            allMatOfPoint=new ArrayList<MatOfPoint>();
            MatOfPoint mop2=new MatOfPoint();
            List<Point> allPoint2=new ArrayList<Point>();
            //點集合的所有座標, area3的6個點,要循序
            allPoint2.add(new Point(0,0));//p1
            allPoint2.add(new Point(0 +direction.x*0.5,0 +direction.y*0.5));//p2
            allPoint2.add(new Point(0 +direction.x*0.5,RoiMat.height()-direction.y*0.5));//p3
            allPoint2.add(new Point(RoiMat.width()-direction.x*0.5,RoiMat.height()-direction.y*0.5));//p4
            allPoint2.add(new Point(RoiMat.width(),RoiMat.height()));//p5
            allPoint2.add(new Point(0,RoiMat.height()));//p6
            mop2.fromList(allPoint2);
            allMatOfPoint.add(mop2);

            //完成填充,area3為白色(255,255,255)
            Imgproc.fillPoly(MaskTemplate, allMatOfPoint,  new Scalar(255,255,255));
            //取到多邊形area3的mat
            //Core.add(RoiMat, RoiMat, dst3,MaskTemplate);
            Core.bitwise_and(RoiMat, RoiMat, dst3,MaskTemplate);
            //area3灰暗化處理
            dst3.convertTo(dst3, -1, 0.5, -50);
            //設為global value,在被貼處還需用到
            setEmbossArea3(dst3);
            //area3-end

        }else{
            RoiMat=null;
        }
    }




    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

    public int getSrcX() {
        return srcX;
    }

    public void setSrcX(int srcX) {
        this.srcX = srcX;
    }

    public int getSrcY() {
        return srcY;
    }

    public void setSrcY(int srcY) {
        this.srcY = srcY;
    }

    public int getSecondX() {
        return secondX;
    }

    public void setSecondX(int secondX) {
        this.secondX = secondX;
    }

    public int getSecondY() {
        return secondY;
    }

    public void setSecondY(int secondY) {
        this.secondY = secondY;
    }

    public Mat getMatWantToSave() {
        return matWantToSave;
    }

    public void setMatWantToSave(Mat matWantToSave) {
        this.matWantToSave = matWantToSave;
    }

    public Mat getEmbossArea1() {
        return EmbossArea1;
    }

    public void setEmbossArea1(Mat embossArea1) {
        EmbossArea1 = embossArea1;
    }

    public Mat getEmbossArea2() {
        return EmbossArea2;
    }

    public void setEmbossArea2(Mat embossArea2) {
        EmbossArea2 = embossArea2;
    }

    public Mat getEmbossArea3() {
        return EmbossArea3;
    }

    public void setEmbossArea3(Mat embossArea3) {
        EmbossArea3 = embossArea3;
    }

    public Point getInnerP1() {
        return innerP1;
    }

    public void setInnerP1(double d,double e) {
        Point tmpPoint=new Point(d,e);
        this.innerP1 = tmpPoint;
    }

    public Point getInnerP2() {
        return innerP2;
    }

    public void setInnerP2(double d,double e) {
        Point tmpPoint=new Point(d,e);
        this.innerP2 = tmpPoint;
    }

}
Result

opencv_emboss_rectangle.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

spring bootでメール送信

メモ

pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
application.yml
spring:
  mail:
    host: smtp.●●.●●(gmailなら「smtp.gmail.com」)
    port: 587
    username: (メールアドレス)
    password: (パスワード)
    properties.mail.smtp.auth: true
    properties.mail.smtp.starttls.enable: true
sample
@Autowired
    private MailSender sender;

    public void sendMail() {
        SimpleMailMessage msg = new SimpleMailMessage();

        msg.setFrom("送信元メールアドレス");
        msg.setTo("送信先メールアドレス");
        msg.setSubject("件名入力欄");
        msg.setText("本文入力欄");

        this.sender.send(msg);
    }

sampleはクラス内に書くこと。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Polyline select Roi Into Another Img

Goal

Test OpenCV polyline select roi into another img.

OpenCV_SettingRoiByPolylineIntoAnotherImg.java
import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class OpenCV_SettingRoiByPolylineIntoAnotherImg {

    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmjavaSwing;

    public List<Point> allPoint=new ArrayList<Point>();
    private List<Integer> pointX=new ArrayList<Integer>();
    private List<Integer> pointY=new ArrayList<Integer>();
    private int maxX,maxY,minX,minY;
    private Mat globalRoi;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_SettingRoiByPolylineIntoAnotherImg window = new OpenCV_SettingRoiByPolylineIntoAnotherImg();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_SettingRoiByPolylineIntoAnotherImg() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0227.jpg");
        final Mat rightImg = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0250.jpg");

        BufferedImage image=matToBufferedImage(source);
        BufferedImage imageRight=matToBufferedImage(rightImg);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("使用多邊形擷取為不規則ROI複製到另一張影像");
        frmjavaSwing.setBounds(100, 100, 922, 482);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblLocation = new JLabel("");
        lblLocation.setBounds(10, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation);

        final JLabel lblLocation2 = new JLabel("");
        lblLocation2.setBounds(121, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation2);

        JPanel panel = new JPanel();
        panel.setBounds(10, 106, 200, 242);
        frmjavaSwing.getContentPane().add(panel);

        final JLabel lblNewLabel = new JLabel("");
        panel.add(lblNewLabel);


        lblNewLabel.setIcon(new ImageIcon(image));

        final JLabel label_Right = new JLabel("");
        label_Right.setBounds(430, 92, 449, 346);

        label_Right.setIcon(new ImageIcon(imageRight));
        frmjavaSwing.getContentPane().add(label_Right);

        JButton btnNewButton = new JButton("封閉化");
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                BufferedImage newImage=matToBufferedImage(paintAndSetPolyClose());
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnNewButton.setBounds(243, 10, 89, 25);
        frmjavaSwing.getContentPane().add(btnNewButton);

        final JLabel Label_mid = new JLabel("");
        Label_mid.setBounds(220, 106, 200, 242);
        frmjavaSwing.getContentPane().add(Label_mid);

        JButton btnNewButton_1 = new JButton("擷取為不規則ROI並貼上");
        btnNewButton_1.setBounds(342, 10, 175, 25);
        frmjavaSwing.getContentPane().add(btnNewButton_1);

        final JSlider sliderX = new JSlider();

        sliderX.setMaximum(465);
        sliderX.setBounds(577, 10, 248, 25);
        frmjavaSwing.getContentPane().add(sliderX);

        JLabel lblNewLabel_1 = new JLabel("X:");
        lblNewLabel_1.setBounds(542, 10, 34, 15);
        frmjavaSwing.getContentPane().add(lblNewLabel_1);

        final JSlider sliderY = new JSlider();

        sliderY.setMaximum(315);
        sliderY.setBounds(577, 45, 248, 25);
        frmjavaSwing.getContentPane().add(sliderY);

        JLabel lblY = new JLabel("Y:");
        lblY.setBounds(542, 45, 34, 15);
        frmjavaSwing.getContentPane().add(lblY);

        final JLabel showX_Val = new JLabel("50");
        showX_Val.setBounds(835, 10, 46, 15);
        frmjavaSwing.getContentPane().add(showX_Val);

        final JLabel showY_Val = new JLabel("50");
        showY_Val.setBounds(835, 45, 46, 15);
        frmjavaSwing.getContentPane().add(showY_Val);

        sliderX.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showX_Val.setText(sliderX.getValue()+"");

                Mat currentRightImg = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0250.jpg");
                //若是currentRightImg使用initialize()的rightImg會有疊圖現象
                Mat rightSideImg=pasteToAnother(sliderX.getValue(),sliderY.getValue(), getGlobalRoi(),currentRightImg);
                BufferedImage   newImage=matToBufferedImage(rightSideImg);
                label_Right.setIcon(new ImageIcon(newImage));
            }
        });

        sliderY.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent arg0) {
                showY_Val.setText(sliderY.getValue()+"");

                Mat currentRightImg = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0250.jpg");
                Mat rightSideImg=pasteToAnother(sliderX.getValue(),sliderY.getValue(), getGlobalRoi(),currentRightImg);
                BufferedImage   newImage=matToBufferedImage(rightSideImg);
                label_Right.setIcon(new ImageIcon(newImage));

            }
        });
        //Listener滑鼠點擊的點
        lblNewLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblLocation2.setText("");
                lblLocation.setText("加入點:X:"+arg0.getX()+",Y:"+arg0.getY());


                BufferedImage newImage=matToBufferedImage(paintPointAndPolylines(arg0.getX(),arg0.getY()));
                lblNewLabel.setIcon(new ImageIcon(newImage));

            }
        });

        //點擊擷取為不規則ROI按鈕
        btnNewButton_1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                Mat roi=getRoi(source);
                BufferedImage newImage=matToBufferedImage(roi);
                Label_mid.setIcon(new ImageIcon(newImage));

                //set global data
                setGlobalRoi(roi);


                //paste to another one,default position is (50,50)
                Mat rightSideImg=pasteToAnother(50,50, roi,rightImg);
                newImage=matToBufferedImage(rightSideImg);
                label_Right.setIcon(new ImageIcon(newImage));

            }
        });
    }
    //繪出點及所有的線
    public Mat paintPointAndPolylines(int x,int y){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0227.jpg");
        List<Integer> pointX=getPointX();
        List<Integer> pointY=getPointY();
        List<Point> allPoint=getAllPoint();
        allPoint.add(new Point(x,y));
        setAllPoint(allPoint);

        pointX.add(x);
        pointY.add(y);
        setPointX(pointX);
        setPointY(pointY);

        //畫滑鼠點擊的點
        Imgproc.circle(src, new Point(x,y), 2, new Scalar(0,55,255),2);

        //畫出Polyline
        if(allPoint.size()>=2){
            MatOfPoint mop1=new MatOfPoint();
            List<MatOfPoint> allMatOfPoint=new ArrayList<MatOfPoint>();
            mop1.fromList(allPoint);
            allMatOfPoint.add(mop1);
            Imgproc.polylines(src, allMatOfPoint, false, new Scalar(255,255,255), 2);

        }

        return src;

    }

    //封閉不規則線
    public Mat paintAndSetPolyClose(){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0227.jpg");
        List<Point> allPoint=getAllPoint();
        //畫出Polyline
        if(allPoint.size()>=2){
            MatOfPoint mop1=new MatOfPoint();
            List<MatOfPoint> allMatOfPoint=new ArrayList<MatOfPoint>();
            mop1.fromList(allPoint);
            allMatOfPoint.add(mop1);
            Imgproc.polylines(src, allMatOfPoint, true, new Scalar(255,255,255), 2);

        }

        return src;
    }
    //取到ROI
    public Mat getRoi(Mat src){
        Mat RoiMat=new Mat();
        List<Integer> pointX=getPointX();
        List<Integer> pointY=getPointY();


        //找出所有點集合的min及max,以利建立ROI
        int X0,Y0,X1,Y1,maxX,maxY,minX,minY;
        maxX=Collections.max(pointX);
        maxY=Collections.max(pointY);
        minX=Collections.min(pointX);
        minY= Collections.min(pointY);

        //貼至大圖還需要再用到
        setMaxX(maxX);
        setMinX(minX);
        setMaxY(maxY);
        setMinY(minY);


        //那些點可建立的矩形ROI
        Rect rect=new Rect(new Point(minX,minY),new Point(maxX,maxY));
        RoiMat=src.submat(rect);

        //像photoshop的mask,0黑不作用
        Mat  MaskTemplate=new Mat(RoiMat.size(),CvType.CV_8UC1,new Scalar(0));

        List<Point> allPoint=getAllPoint();
        List<Point> newPointSet=new ArrayList<Point>();
        // System.out.println("size="+allPoint.size());
        List<MatOfPoint> allMatOfPoint=new ArrayList<MatOfPoint>();
        MatOfPoint mop1=new MatOfPoint();
        Point tmpPoint;
        //點集合的所有座標要重置,ROI的左上角座標是(minX,minY),全部都要減去左上以歸零
        for(int i=0;i<allPoint.size();i++){
            tmpPoint=allPoint.get(i);
            newPointSet.add(new Point(tmpPoint.x-minX,tmpPoint.y-minY));
        }

        mop1.fromList(newPointSet);
        allMatOfPoint.add(mop1);
        //使用fillPoly填充我們要的區域,255白色,為作用區
        Imgproc.fillPoly(MaskTemplate, allMatOfPoint,  new Scalar(255,255,255));

        //不規則的mat
        Mat dst=new Mat();
        Core.bitwise_and(RoiMat, RoiMat, dst,MaskTemplate);
        //用Core.add會較亮
        //Core.add(RoiMat, RoiMat, dst,MaskTemplate );
        return dst;
    }


    //ROI貼至另一張影像,roi是不規則子影像,anotherImg是預被貼上的另一張影像,x,y是該座標
    public Mat pasteToAnother(int x,int y,Mat roi,Mat anotherImg){

        Rect dstRoi=new Rect(new Point(x,y),new Point(x+getMaxX()-getMinX(),y+getMaxY()-getMinY()));
        Mat destinationROI = anotherImg.submat( dstRoi );
        roi.copyTo( destinationROI , roi);

        return anotherImg;

    }




    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }



    public List<Point> getAllPoint() {
        return allPoint;
    }

    public void setAllPoint(List<Point> allPoint) {
        this.allPoint = allPoint;
    }

    public List<Integer> getPointX() {
        return pointX;
    }

    public void setPointX(List<Integer> pointX) {
        this.pointX = pointX;
    }

    public List<Integer> getPointY() {
        return pointY;
    }

    public void setPointY(List<Integer> pointY) {
        this.pointY = pointY;
    }

    public int getMaxX() {
        return maxX;
    }

    public void setMaxX(int maxX) {
        this.maxX = maxX;
    }

    public int getMaxY() {
        return maxY;
    }

    public void setMaxY(int maxY) {
        this.maxY = maxY;
    }

    public int getMinX() {
        return minX;
    }

    public void setMinX(int minX) {
        this.minX = minX;
    }

    public int getMinY() {
        return minY;
    }

    public void setMinY(int minY) {
        this.minY = minY;
    }

    public Mat getGlobalRoi() {
        return globalRoi;
    }

    public void setGlobalRoi(Mat globalRoi) {
        this.globalRoi = globalRoi;
    }

}
Result

opencv_setting_roi_by_polyline_into_another_img.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : RoiForRectangleRoi For Rectangle

Goal

Test OpenCV roi for rectangle.

OpenCV_RoiForRectangle.java
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Panel;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import java.awt.Color;
import java.awt.image.BufferedImage;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class OpenCV_RoiForRectangle {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmjavaSwing;

    public int srcX=0;
    public int srcY=0;

    public int secondX=0;
    public int secondY=0;

    public Mat matWantToSave;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_RoiForRectangle window = new OpenCV_RoiForRectangle();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public OpenCV_RoiForRectangle() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0625.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("擷取ROI(區塊)練習");
        frmjavaSwing.setBounds(100, 100, 763, 425);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblLocation = new JLabel("");
        lblLocation.setBounds(10, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation);

        final JLabel lblLocation2 = new JLabel("");
        lblLocation2.setBounds(158, 10, 112, 25);
        frmjavaSwing.getContentPane().add(lblLocation2);

        JPanel panel = new JPanel();
        panel.setBounds(10, 45, 429, 348);
        frmjavaSwing.getContentPane().add(panel);

        final JLabel lblNewLabel = new JLabel("");
        panel.add(lblNewLabel);
        lblNewLabel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent arg0) {
                lblLocation2.setText("X:"+arg0.getX()+",Y:"+arg0.getY());

                BufferedImage newImage=matToBufferedImage(paintRectangle(arg0.getX(),arg0.getY()));
                lblNewLabel.setIcon(new ImageIcon(newImage));


            }
        });

        final JLabel lblRoi = new JLabel("");
        lblRoi.setBounds(444, 45, 288, 348);
        frmjavaSwing.getContentPane().add(lblRoi);


        lblNewLabel.setIcon(new ImageIcon(image));

        JButton btnNewButton = new JButton("擷取ROI");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Mat RoiMat=getRoi();
                if (RoiMat!=null){
                    BufferedImage newImage=matToBufferedImage(RoiMat);
                    lblRoi.setText("");
                    lblRoi.setIcon(new ImageIcon(newImage));
                }else{
                    lblRoi.setText("未規劃ROI區塊!");
                }

            }
        });
        btnNewButton.setBounds(278, 10, 97, 25);
        frmjavaSwing.getContentPane().add(btnNewButton);

        JButton btnNewButton_1 = new JButton("Save");
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                if(getMatWantToSave()!=null){
                    Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0625_sub.jpg",getMatWantToSave());
                }else{
                    System.out.println("未擷取ROI區塊!");
                }


            }
        });
        btnNewButton_1.setBounds(398, 10, 89, 25);
        frmjavaSwing.getContentPane().add(btnNewButton_1);



        lblNewLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblLocation2.setText("");
                lblLocation.setText("初始點:X:"+arg0.getX()+",Y:"+arg0.getY());
                setSrcX(arg0.getX());
                setSrcY(arg0.getY());
                BufferedImage newImage=matToBufferedImage(paintPoint(arg0.getX(),arg0.getY()));
                lblNewLabel.setIcon(new ImageIcon(newImage));
            }
        });



    }

    public Mat paintPoint(int x,int y){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0625.jpg");
        Imgproc.circle(src, new Point(x,y), 2, new Scalar(0,55,255),2);
        return src;

    }

    public Mat paintRectangle(int x,int y){
        Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0625.jpg");
        Point srcPoint=new Point(getSrcX(),getSrcY());
        Imgproc.rectangle(src, srcPoint, new Point(x,y), new Scalar(0,0,255),2);
        setSecondX(x);
        setSecondY(y);
        return src;

    }

    public Mat getRoi(){
        Mat RoiMat;
        if(getSecondX()>0 && getSecondY()>0){
            Mat source=
                    Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0625.jpg");
            Rect roi=new Rect(new Point(getSrcX(),getSrcY()),new Point(getSecondX(),getSecondY()));

            RoiMat=source.submat(roi);
            setMatWantToSave(RoiMat);
        }else{
            RoiMat=null;
        }


        return RoiMat;

    }




    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

    public int getSrcX() {
        return srcX;
    }

    public void setSrcX(int srcX) {
        this.srcX = srcX;
    }

    public int getSrcY() {
        return srcY;
    }

    public void setSrcY(int srcY) {
        this.srcY = srcY;
    }

    public int getSecondX() {
        return secondX;
    }

    public void setSecondX(int secondX) {
        this.secondX = secondX;
    }

    public int getSecondY() {
        return secondY;
    }

    public void setSecondY(int secondY) {
        this.secondY = secondY;
    }

    public Mat getMatWantToSave() {
        return matWantToSave;
    }

    public void setMatWantToSave(Mat matWantToSave) {
        this.matWantToSave = matWantToSave;
    }
}
Result

DSC_0625_sub.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Rect Contain Points

Goal

Test OpenCV rect contain points.

OpenCV_RectangleContain.java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class OpenCV_RectangleContain {

    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}

    public static void main(String[] args){
        Mat img = Mat.zeros(250, 250, CvType.CV_8UC3);

        List<Integer> pointX=new ArrayList<Integer>();
        List<Integer> pointY=new ArrayList<Integer>();
        int X,Y,maxX,maxY,minX,minY;
        for(int i=0;i<20;i++){
            X=(int)(Math.random()*200+10);
            Y=(int)(Math.random()*200+10);
            Imgproc.circle(img, new Point(X,Y), 2, new Scalar(0, 255, 0));
            pointX.add(X);
            pointY.add(Y);

        }
        maxX= Collections.max(pointX);
        maxY=Collections.max(pointY);
        minX=Collections.min(pointX);
        minY=Collections.min(pointY);

        Imgproc.rectangle(img, new Point(minX,minY), new Point(maxX,maxY), new Scalar(0, 0, 255));

        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\rectContainPoint.jpg", img );
    }


}
Result

rectContainPoint.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Flood Fill For Fun

Goal

Test OpenCV flood fill.

OpenCV_FloodFillForFun.java
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JLabel;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

public class OpenCV_FloodFillForFun {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
    private JFrame frmOpencv;
    private Mat paintMat=Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\floodFill-template.png");
    private Color color;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_FloodFillForFun window = new OpenCV_FloodFillForFun();
                    window.frmOpencv.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public OpenCV_FloodFillForFun() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {



        final BufferedImage image=matToBufferedImage(paintMat);

        frmOpencv = new JFrame();
        frmOpencv.setTitle("opencv 填充顏色練習");
        frmOpencv.getContentPane().setBackground(Color.LIGHT_GRAY);
        frmOpencv.setBounds(100, 100, 476, 300);
        frmOpencv.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmOpencv.getContentPane().setLayout(null);

        final JLabel lblShowXY = new JLabel("");
        lblShowXY.setBounds(22, 218, 124, 23);
        frmOpencv.getContentPane().add(lblShowXY);


        JPanel panel = new JPanel();

        final JLabel lblPaintLabel = new JLabel("");
        lblPaintLabel.setIcon(new ImageIcon(image));
        panel.add(lblPaintLabel);

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                lblShowXY.setText("X:"+arg0.getX()+",Y:"+arg0.getY());
                BufferedImage newImage=matToBufferedImage(floodFill(paintMat,getColor(),arg0.getX(),arg0.getY()) );
                lblPaintLabel.setIcon(new ImageIcon(newImage));
            }
        });
        panel.setBounds(22, 23, 324, 181);
        frmOpencv.getContentPane().add(panel);

        JButton btnNewButton = new JButton("清除");
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                paintMat=Imgcodecs.imread("C://opencv3.1//samples//done-floodFill-template.png");
                BufferedImage newImage=matToBufferedImage(paintMat);
                lblPaintLabel.setIcon(new ImageIcon(newImage));
            }
        });
        btnNewButton.setBounds(356, 151, 87, 23);
        frmOpencv.getContentPane().add(btnNewButton);

        JButton btnNewButton_1 = new JButton("Save");
        btnNewButton_1.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                save(paintMat);
            }
        });
        btnNewButton_1.setBounds(356, 181, 87, 23);
        frmOpencv.getContentPane().add(btnNewButton_1);

        final JPanel panel_Color = new JPanel();
        panel_Color.setBorder(new LineBorder(new Color(0, 0, 0), 2));
        panel_Color.setBounds(363, 47, 80, 94);
        frmOpencv.getContentPane().add(panel_Color);

        JLabel lblNewLabel = new JLabel("目前顏色");
        lblNewLabel.setBounds(364, 22, 79, 15);
        frmOpencv.getContentPane().add(lblNewLabel);

        panel_Color.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                lblShowXY.setText("X:"+e.getX()+",Y:"+e.getY());


                Color c;
                c = JColorChooser.showDialog(((Component) e.getSource())
                        .getParent(), "Choose Color", Color.blue);
                panel_Color.setBackground(c);
                setColor(c);
            }
        });

    }

    public Mat floodFill(Mat src,Color c,int PntX,int PntY){
        Point seedPoint = new Point(PntX,PntY);
        Mat mask = new Mat();
        Rect rect = new Rect();
        Imgproc.floodFill(src, mask, seedPoint, new Scalar(c.getBlue(),c.getGreen(),c.getRed()), rect, new Scalar(10,10,10),new Scalar(20,20,20), 4);

        return src;
    }

    public void save(Mat src){
        Imgcodecs.imwrite("C://opencv249//floodFill.jpg",src);
    }


    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}
Result

opencv_flood_fill_for_fun.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop : OpenCV Flood Fill

Goal

Test OpenCV flood fill.

OpenCV_FloodFill.java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class OpenCV_FloodFill {

    public static void main(String[] args){
        try{
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            Mat src = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\test-floodFill.jpg");
            System.out.println("Imgproc.FLOODFILL_FIXED_RANGE="+Imgproc.FLOODFILL_FIXED_RANGE);
            System.out.println("Imgproc.FLOODFILL_MASK_ONLY="+ Imgproc.FLOODFILL_MASK_ONLY);
            Point seedPoint = new Point(85,89);
            Mat mask = new Mat();
            Rect rect = new Rect();
            Imgproc.floodFill(src, mask, seedPoint, new Scalar(0,130,120), rect, new Scalar(20,20,20),new Scalar(20,20,20), 4);
            Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\test-floodFill_do.jpg", src);


        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
Result

test-floodFill_do.jpg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Desktop :OpenCV Histogram

Goal

Test OpenCV histogram.

OpenCV_Histogram.java
import java.awt.EventQueue;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.image.BufferedImage;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

public class OpenCV_Histogram {
    static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}
    private JFrame frmjavaSwing;

    /**
     *  Launch the application.
     */
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OpenCV_Histogram window = new OpenCV_Histogram();
                    window.frmjavaSwing.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the application.
     */
    public OpenCV_Histogram() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        final Mat source = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\lena.jpg");

        BufferedImage image=matToBufferedImage(source);

        frmjavaSwing = new JFrame();
        frmjavaSwing.setTitle("opencv 直方圖統計練習");
        frmjavaSwing.setBounds(100, 100, 780, 620);
        frmjavaSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmjavaSwing.getContentPane().setLayout(null);

        final JLabel lblNewLabel_histogram = new JLabel("");
        lblNewLabel_histogram.setBounds(250, 10, 512, 551);
        frmjavaSwing.getContentPane().add(lblNewLabel_histogram);

        final JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(5, 60, image.getHeight()+10, image.getWidth()+10);
        lblNewLabel.setIcon(new ImageIcon(image));
        frmjavaSwing.getContentPane().add(lblNewLabel);

        JButton btn3 = new JButton("直方圖統計");
        btn3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                BufferedImage newImage=matToBufferedImage(getHistogram(source));
                lblNewLabel_histogram.setIcon(new ImageIcon(newImage));
            }
        });
        btn3.setBounds(10, 10, 114, 23);
        frmjavaSwing.getContentPane().add(btn3);

    }
    public Mat getHistogram(Mat source){
        List<Mat> bgr_planes = new ArrayList<Mat>();
        List<Mat> bgr_plane = new ArrayList<Mat>();
        Core.split(source, bgr_planes);
        //bgr_plane.add(bgr_planes.get(0));
        MatOfInt histSize = new MatOfInt(256);
        MatOfFloat histRange = new MatOfFloat(0,256);
        Mat hist = new  Mat();
        int hist_w = 512;
        int hist_h = 500;
        long bin_w;
        Mat histImage = new Mat(hist_h, hist_w, CvType.CV_8UC3);

        for(int j=0;j<3;j++){


            bgr_plane.clear();
            bgr_plane.add(bgr_planes.get(j));

            Imgproc.calcHist((java.util.List<Mat>) bgr_plane, new MatOfInt(0),new Mat(), hist, histSize, histRange);
            //System.out.println("hist="+b_hist.dump()+"size="+b_hist.size());


            bin_w = Math.round((double) (hist_w / 256));

            Core.normalize(hist, hist, 0, histImage.rows(), Core.NORM_MINMAX);



            for (int i = 1; i < 256; i++) {

                if (j==0){
                    Imgproc.line(histImage, new Point(bin_w * (i - 1),hist_h- Math.round(hist.get( i-1,0)[0])),
                            new Point(bin_w * (i), hist_h-Math.round(Math.round(hist.get(i, 0)[0]))),
                            new Scalar(255, 0, 0), 2, 8, 0);
                }else if (j==1){
                    Imgproc.line(histImage, new Point(bin_w * (i - 1),hist_h- Math.round(hist.get( i-1,0)[0])),
                            new Point(bin_w * (i), hist_h-Math.round(Math.round(hist.get(i, 0)[0]))),
                            new  Scalar( 0,255, 0), 2, 8, 0);
                }else if (j==2){
                    Imgproc.line(histImage, new Point(bin_w * (i - 1),hist_h- Math.round(hist.get( i-1,0)[0])),
                            new Point(bin_w * (i), hist_h-Math.round(Math.round(hist.get(i, 0)[0]))),
                            new  Scalar(0, 0,255), 2, 8, 0);
                }


            }
        }
        return histImage;

    }
    public BufferedImage matToBufferedImage(Mat matrix) {
        int cols = matrix.cols();
        int rows = matrix.rows();
        int elemSize = (int)matrix.elemSize();
        byte[] data = new byte[cols * rows * elemSize];
        int type;
        matrix.get(0, 0, data);
        switch (matrix.channels()) {
            case 1:
                type = BufferedImage.TYPE_BYTE_GRAY;
                break;
            case 3:
                type = BufferedImage.TYPE_3BYTE_BGR;
                // bgr to rgb
                byte b;
                for(int i=0; i<data.length; i=i+3) {
                    b = data[i];
                    data[i] = data[i+2];
                    data[i+2] = b;
                }
                break;
            default:
                return null;
        }
        BufferedImage image2 = new BufferedImage(cols, rows, type);
        image2.getRaster().setDataElements(0, 0, cols, rows, data);
        return image2;
    }
}
Result

opencv_histogram.JPG

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む