diff --git a/.classpath b/.classpath index d2bc4e0..0ca1374 100644 --- a/.classpath +++ b/.classpath @@ -1,38 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 041a036..c97209a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -13,16 +13,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - uses: actions/checkout@v3 + - name: Set up JDK 8 + uses: actions/setup-java@v3 with: - java-version: 1.8 - - name: Cache Maven packages - uses: actions/cache@v1 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + distribution: corretto + java-version: 8 + cache: maven - name: Build with Maven run: mvn -B package --file pom.xml \ No newline at end of file diff --git a/.gitignore b/.gitignore index b83d222..f281eaa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target/ +/images/ +/.sts4-cache/ diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..d4313d4 --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 9de2ed6..c79b505 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -11,5 +11,6 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.source=1.8 diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/constants/Configurations.java b/src/main/java/jp/evosystem/objectSizeMeasurer/constants/Configurations.java index 73e2060..3f3c4b7 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/constants/Configurations.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/constants/Configurations.java @@ -1,74 +1,74 @@ -package jp.evosystem.objectSizeMeasurer.constants; - -/** - * 環境設定. - * - * @author evosystem - */ -public interface Configurations { - - /** - * デバッグモードを有効化するかどうか. - */ - boolean ENABLE_DEBUG_MODE = false; - - /** - * 使用するブラーのサイズ(奇数). - */ - int USE_GAUSSIAN_BLUR_SIZE = 7; - - /** - * 使用するCanny処理のしきい値1. - */ - int USE_CANNY_THRESHOLD_1 = 50; - - /** - * 使用するCanny処理のしきい値2. - */ - int USE_CANNY_THRESHOLD_2 = 100; - - /** - * 使用する輪郭の面積の最小値. - */ - int USE_CONTOUR_AREA_MIN_THRESHOLD = 100; - - /** - * 使用する輪郭の面積の最大値. - */ - int USE_CONTOUR_AREA_MAX_THRESHOLD = 1000; - - /** - * 使用するピクセル/cm. - */ - int USE_PIXEL_PER_CENTIMETER = 40; - - /** - * 全ての輪郭を描画するかどうか. - */ - boolean DRAW_ALL_CONTOURS = false; - - /** - * 回転を考慮しない外接矩形を描画するかどうか. - */ - boolean DRAW_RECTANGLE = false; - - /** - * 処理結果をファイルに出力するかどうか. - */ - boolean ENABLE_RECORDING = true; - - /** - * 対象の画像ファイルのパス. - */ - String TARGET_IMAGE_FILE_PATH = "images/example_01.jpg"; - - /** - * 対象の動画ファイルのパス. - */ - String TARGET_VIDEO_FILE_PATH = "videos/example.mp4"; - - /** - * 使用するWebカメラのデバイス番号. - */ - int TARGET_DEVICE_NUMBER = 0; +package jp.evosystem.objectSizeMeasurer.constants; + +/** + * 環境設定. + * + * @author evosystem + */ +public interface Configurations { + + /** + * デバッグモードを有効化するかどうか. + */ + boolean ENABLE_DEBUG_MODE = false; + + /** + * 使用するブラーのサイズ(奇数). + */ + int USE_GAUSSIAN_BLUR_SIZE = 7; + + /** + * 使用するCanny処理のしきい値1. + */ + int USE_CANNY_THRESHOLD_1 = 50; + + /** + * 使用するCanny処理のしきい値2. + */ + int USE_CANNY_THRESHOLD_2 = 100; + + /** + * 使用する輪郭の面積の最小値. + */ + int USE_CONTOUR_AREA_MIN_THRESHOLD = 100; + + /** + * 使用する輪郭の面積の最大値. + */ + int USE_CONTOUR_AREA_MAX_THRESHOLD = 1000; + + /** + * 使用するピクセル/cm. + */ + int USE_PIXEL_PER_CENTIMETER = 40; + + /** + * 全ての輪郭を描画するかどうか. + */ + boolean DRAW_ALL_CONTOURS = false; + + /** + * 回転を考慮しない外接矩形を描画するかどうか. + */ + boolean DRAW_RECTANGLE = false; + + /** + * 処理結果をファイルに出力するかどうか. + */ + boolean ENABLE_RECORDING = true; + + /** + * 対象の画像ファイルのパス. + */ + String TARGET_IMAGE_FILE_PATH = "images/example_01.jpg"; + + /** + * 対象の動画ファイルのパス. + */ + String TARGET_VIDEO_FILE_PATH = "videos/example.mp4"; + + /** + * 使用するWebカメラのデバイス番号. + */ + int TARGET_DEVICE_NUMBER = 0; } \ No newline at end of file diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/AbstractObjectSize.java b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/AbstractObjectSize.java index 629b773..9d25a60 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/AbstractObjectSize.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/AbstractObjectSize.java @@ -1,188 +1,188 @@ -package jp.evosystem.objectSizeMeasurer.mains; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.bytedeco.javacpp.indexer.FloatRawIndexer; -import org.bytedeco.opencv.global.opencv_core; -import org.bytedeco.opencv.global.opencv_imgproc; -import org.bytedeco.opencv.opencv_core.Mat; -import org.bytedeco.opencv.opencv_core.MatVector; -import org.bytedeco.opencv.opencv_core.Point; -import org.bytedeco.opencv.opencv_core.RotatedRect; -import org.bytedeco.opencv.opencv_core.Scalar; -import org.bytedeco.opencv.opencv_core.Size; - -import jp.evosystem.objectSizeMeasurer.constants.Configurations; -import jp.evosystem.objectSizeMeasurer.utils.MathHelper; - -/** - * 画像内の物体の大きさを測定. - * - * @author evosystem - */ -public abstract class AbstractObjectSize { - - /** - * 古い描画処理を使用するかどうか. - */ - private static boolean USE_ALTERNATIVE_DRAWING = false; - - /** - * 画像処理. - * - * @param targetImageMat - */ - protected static void processTargetImage(Mat targetImageMat) { - processTargetImage(targetImageMat, Configurations.USE_CONTOUR_AREA_MIN_THRESHOLD, - Configurations.USE_CONTOUR_AREA_MAX_THRESHOLD); - } - - /** - * 画像処理. - * - * @param targetImageMat - * @param useContourAreaMinThreshold - * @param useContourAreaMaxThreshold - */ - protected static void processTargetImage(Mat targetImageMat, int useContourAreaMinThreshold, - int useContourAreaMaxThreshold) { - // グレースケール画像を作成 - Mat targetImageMatGray = new Mat(); - opencv_imgproc.cvtColor(targetImageMat, targetImageMatGray, opencv_imgproc.COLOR_BGR2GRAY); - - // ブラー画像を作成 - Mat targetImageMatBlur = new Mat(); - opencv_imgproc.GaussianBlur(targetImageMatGray, targetImageMatBlur, - new Size(Configurations.USE_GAUSSIAN_BLUR_SIZE, Configurations.USE_GAUSSIAN_BLUR_SIZE), 0); - - // エッジ抽出 - Mat targetImageMatCanny = new Mat(); - opencv_imgproc.Canny(targetImageMatBlur, targetImageMatCanny, Configurations.USE_CANNY_THRESHOLD_1, - Configurations.USE_CANNY_THRESHOLD_2); - Mat targetImageMatClose = new Mat(); - opencv_imgproc.morphologyEx(targetImageMatCanny, targetImageMatClose, opencv_imgproc.MORPH_CLOSE, new Mat()); - - // debug - if (Configurations.ENABLE_DEBUG_MODE) { - opencv_core.copyTo(targetImageMatClose, targetImageMat, new Mat()); - } - - // 輪郭を検出 - MatVector targetImageContours = new MatVector(); - Mat targetImageHierarchy = new Mat(); - opencv_imgproc.findContours(targetImageMatClose, targetImageContours, targetImageHierarchy, - opencv_imgproc.RETR_EXTERNAL, - opencv_imgproc.CHAIN_APPROX_SIMPLE); - System.out.println("検出した輪郭数:" + targetImageContours.size()); - - // 使用するものだけ抽出 - try (MatVector useTargetImageContours = new MatVector( - Arrays.stream(targetImageContours.get()) - .filter(contour -> { - double contourArea = opencv_imgproc.contourArea(contour); - return useContourAreaMinThreshold < contourArea && contourArea < useContourAreaMaxThreshold; - }) - .collect(Collectors.toList()).toArray(new Mat[0]))) { - System.out.println("使用する輪郭数:" + useTargetImageContours.size()); - - // 全ての輪郭を描画 - if (Configurations.DRAW_ALL_CONTOURS) { - opencv_imgproc.drawContours(targetImageMat, useTargetImageContours, -1, Scalar.RED, 3, 0, new Mat(), 1, - new Point(0, 0)); - } - - // 全ての輪郭に対して実行 - for (Mat contour : useTargetImageContours.get()) { - // 輪郭に対する外接矩形を取得 - RotatedRect box = opencv_imgproc.minAreaRect(contour); - - // 回転を考慮しない外接矩形を描画 - if (Configurations.DRAW_RECTANGLE) { - opencv_imgproc.rectangle(targetImageMat, box.boundingRect(), Scalar.GREEN); - } - - // 外接矩形の4点の座標を取得(Mat型) - Mat points = new Mat(); - opencv_imgproc.boxPoints(box, points); - - // 外接矩形の4点の座標(Point型リスト) - // tl, tr, br, blの順 - List pointList = new ArrayList<>(); - - // 外接矩形の4辺を描画 - // drawContoursが動かないため4辺をそれぞれ線で描画 - FloatRawIndexer rawIndexer = points.createIndexer(); - for (int i = 0; i < points.rows(); i++) { - Point point1 = new Point((int) rawIndexer.get(i, 0), (int) rawIndexer.get(i, 1)); - Point point2 = new Point((int) rawIndexer.get(((i + 1) % 4), 0), - (int) rawIndexer.get(((i + 1) % 4), 1)); - opencv_imgproc.line(targetImageMat, point1, point2, Scalar.BLUE); - pointList.add(point1); - } - - // 4点の座標を並び替え - pointList = MathHelper.orderPoints2(pointList); - - // 4点の座標に円を描画 - for (Point point : pointList) { - opencv_imgproc.circle(targetImageMat, point, 5, Scalar.RED, -1, opencv_imgproc.FILLED, 0); - } - - // 外接矩形の4点の座標をそれぞれ変数に代入 - Point tl = pointList.get(0); - Point tr = pointList.get(1); - Point br = pointList.get(2); - Point bl = pointList.get(3); - - // 中間点を計算 - Point tltr = MathHelper.midPoint(tl, tr); - Point blbr = MathHelper.midPoint(bl, br); - Point tlbl = MathHelper.midPoint(tl, bl); - Point trbr = MathHelper.midPoint(tr, br); - - // 中間点に円を描画 - opencv_imgproc.circle(targetImageMat, tltr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); - opencv_imgproc.circle(targetImageMat, blbr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); - opencv_imgproc.circle(targetImageMat, tlbl, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); - opencv_imgproc.circle(targetImageMat, trbr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); - - // 中間点同士を結ぶ直線を描画 - opencv_imgproc.line(targetImageMat, tltr, blbr, Scalar.BLUE); - opencv_imgproc.line(targetImageMat, tlbl, trbr, Scalar.BLUE); - - // 中間点間の長さを計算 - double width = MathHelper.distance(tltr, blbr) / Configurations.USE_PIXEL_PER_CENTIMETER; - double height = MathHelper.distance(tlbl, trbr) / Configurations.USE_PIXEL_PER_CENTIMETER; - - // 文字を描画 - opencv_imgproc.putText(targetImageMat, String.format("%.2fcm", width), - new Point((tltr.x() - 15), (tltr.y() - 10)), - opencv_imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.BLACK); - opencv_imgproc.putText(targetImageMat, String.format("%.2fcm", height), - new Point((trbr.x() + 10), trbr.y()), - opencv_imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.BLACK); - - if (USE_ALTERNATIVE_DRAWING) { - try { - // MatVectorを作成 - MatVector pointsMatVector = new MatVector(points); - - // 輪郭を描画 - // TODO 動かない - opencv_imgproc.drawContours(targetImageMat, pointsMatVector, -1, Scalar.RED); - } catch (Exception e) { - e.printStackTrace(); - - // 輪郭を描画 - if (Configurations.DRAW_ALL_CONTOURS) { - opencv_imgproc.drawContours(targetImageMat, new MatVector(contour), -1, Scalar.YELLOW); - } - } - } - } - } - } +package jp.evosystem.objectSizeMeasurer.mains; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.bytedeco.javacpp.indexer.FloatRawIndexer; +import org.bytedeco.opencv.global.opencv_core; +import org.bytedeco.opencv.global.opencv_imgproc; +import org.bytedeco.opencv.opencv_core.Mat; +import org.bytedeco.opencv.opencv_core.MatVector; +import org.bytedeco.opencv.opencv_core.Point; +import org.bytedeco.opencv.opencv_core.RotatedRect; +import org.bytedeco.opencv.opencv_core.Scalar; +import org.bytedeco.opencv.opencv_core.Size; + +import jp.evosystem.objectSizeMeasurer.constants.Configurations; +import jp.evosystem.objectSizeMeasurer.utils.MathHelper; + +/** + * 画像内の物体の大きさを測定. + * + * @author evosystem + */ +public abstract class AbstractObjectSize { + + /** + * 古い描画処理を使用するかどうか. + */ + private static boolean USE_ALTERNATIVE_DRAWING = false; + + /** + * 画像処理. + * + * @param targetImageMat + */ + protected static void processTargetImage(Mat targetImageMat) { + processTargetImage(targetImageMat, Configurations.USE_CONTOUR_AREA_MIN_THRESHOLD, + Configurations.USE_CONTOUR_AREA_MAX_THRESHOLD); + } + + /** + * 画像処理. + * + * @param targetImageMat + * @param useContourAreaMinThreshold + * @param useContourAreaMaxThreshold + */ + protected static void processTargetImage(Mat targetImageMat, int useContourAreaMinThreshold, + int useContourAreaMaxThreshold) { + // グレースケール画像を作成 + Mat targetImageMatGray = new Mat(); + opencv_imgproc.cvtColor(targetImageMat, targetImageMatGray, opencv_imgproc.COLOR_BGR2GRAY); + + // ブラー画像を作成 + Mat targetImageMatBlur = new Mat(); + opencv_imgproc.GaussianBlur(targetImageMatGray, targetImageMatBlur, + new Size(Configurations.USE_GAUSSIAN_BLUR_SIZE, Configurations.USE_GAUSSIAN_BLUR_SIZE), 0); + + // エッジ抽出 + Mat targetImageMatCanny = new Mat(); + opencv_imgproc.Canny(targetImageMatBlur, targetImageMatCanny, Configurations.USE_CANNY_THRESHOLD_1, + Configurations.USE_CANNY_THRESHOLD_2); + Mat targetImageMatClose = new Mat(); + opencv_imgproc.morphologyEx(targetImageMatCanny, targetImageMatClose, opencv_imgproc.MORPH_CLOSE, new Mat()); + + // debug + if (Configurations.ENABLE_DEBUG_MODE) { + opencv_core.copyTo(targetImageMatClose, targetImageMat, new Mat()); + } + + // 輪郭を検出 + MatVector targetImageContours = new MatVector(); + Mat targetImageHierarchy = new Mat(); + opencv_imgproc.findContours(targetImageMatClose, targetImageContours, targetImageHierarchy, + opencv_imgproc.RETR_EXTERNAL, + opencv_imgproc.CHAIN_APPROX_SIMPLE); + System.out.println("検出した輪郭数:" + targetImageContours.size()); + + // 使用するものだけ抽出 + try (MatVector useTargetImageContours = new MatVector( + Arrays.stream(targetImageContours.get()) + .filter(contour -> { + double contourArea = opencv_imgproc.contourArea(contour); + return useContourAreaMinThreshold < contourArea && contourArea < useContourAreaMaxThreshold; + }) + .collect(Collectors.toList()).toArray(new Mat[0]))) { + System.out.println("使用する輪郭数:" + useTargetImageContours.size()); + + // 全ての輪郭を描画 + if (Configurations.DRAW_ALL_CONTOURS) { + opencv_imgproc.drawContours(targetImageMat, useTargetImageContours, -1, Scalar.RED, 3, 0, new Mat(), 1, + new Point(0, 0)); + } + + // 全ての輪郭に対して実行 + for (Mat contour : useTargetImageContours.get()) { + // 輪郭に対する外接矩形を取得 + RotatedRect box = opencv_imgproc.minAreaRect(contour); + + // 回転を考慮しない外接矩形を描画 + if (Configurations.DRAW_RECTANGLE) { + opencv_imgproc.rectangle(targetImageMat, box.boundingRect(), Scalar.GREEN); + } + + // 外接矩形の4点の座標を取得(Mat型) + Mat points = new Mat(); + opencv_imgproc.boxPoints(box, points); + + // 外接矩形の4点の座標(Point型リスト) + // tl, tr, br, blの順 + List pointList = new ArrayList<>(); + + // 外接矩形の4辺を描画 + // drawContoursが動かないため4辺をそれぞれ線で描画 + FloatRawIndexer rawIndexer = points.createIndexer(); + for (int i = 0; i < points.rows(); i++) { + Point point1 = new Point((int) rawIndexer.get(i, 0), (int) rawIndexer.get(i, 1)); + Point point2 = new Point((int) rawIndexer.get(((i + 1) % 4), 0), + (int) rawIndexer.get(((i + 1) % 4), 1)); + opencv_imgproc.line(targetImageMat, point1, point2, Scalar.BLUE); + pointList.add(point1); + } + + // 4点の座標を並び替え + pointList = MathHelper.orderPoints2(pointList); + + // 4点の座標に円を描画 + for (Point point : pointList) { + opencv_imgproc.circle(targetImageMat, point, 5, Scalar.RED, -1, opencv_imgproc.FILLED, 0); + } + + // 外接矩形の4点の座標をそれぞれ変数に代入 + Point tl = pointList.get(0); + Point tr = pointList.get(1); + Point br = pointList.get(2); + Point bl = pointList.get(3); + + // 中間点を計算 + Point tltr = MathHelper.midPoint(tl, tr); + Point blbr = MathHelper.midPoint(bl, br); + Point tlbl = MathHelper.midPoint(tl, bl); + Point trbr = MathHelper.midPoint(tr, br); + + // 中間点に円を描画 + opencv_imgproc.circle(targetImageMat, tltr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); + opencv_imgproc.circle(targetImageMat, blbr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); + opencv_imgproc.circle(targetImageMat, tlbl, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); + opencv_imgproc.circle(targetImageMat, trbr, 3, Scalar.BLUE, -1, opencv_imgproc.FILLED, 0); + + // 中間点同士を結ぶ直線を描画 + opencv_imgproc.line(targetImageMat, tltr, blbr, Scalar.BLUE); + opencv_imgproc.line(targetImageMat, tlbl, trbr, Scalar.BLUE); + + // 中間点間の長さを計算 + double width = MathHelper.distance(tltr, blbr) / Configurations.USE_PIXEL_PER_CENTIMETER; + double height = MathHelper.distance(tlbl, trbr) / Configurations.USE_PIXEL_PER_CENTIMETER; + + // 文字を描画 + opencv_imgproc.putText(targetImageMat, String.format("%.2fcm", width), + new Point((tltr.x() - 15), (tltr.y() - 10)), + opencv_imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.BLACK); + opencv_imgproc.putText(targetImageMat, String.format("%.2fcm", height), + new Point((trbr.x() + 10), trbr.y()), + opencv_imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.BLACK); + + if (USE_ALTERNATIVE_DRAWING) { + try { + // MatVectorを作成 + MatVector pointsMatVector = new MatVector(points); + + // 輪郭を描画 + // TODO 動かない + opencv_imgproc.drawContours(targetImageMat, pointsMatVector, -1, Scalar.RED); + } catch (Exception e) { + e.printStackTrace(); + + // 輪郭を描画 + if (Configurations.DRAW_ALL_CONTOURS) { + opencv_imgproc.drawContours(targetImageMat, new MatVector(contour), -1, Scalar.YELLOW); + } + } + } + } + } + } } \ No newline at end of file diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/ImageFileObjectSize.java b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/ImageFileObjectSize.java index d37aae8..b9b13c4 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/ImageFileObjectSize.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/ImageFileObjectSize.java @@ -1,59 +1,59 @@ -package jp.evosystem.objectSizeMeasurer.mains; - -import java.io.File; - -import javax.swing.WindowConstants; - -import org.bytedeco.javacv.CanvasFrame; -import org.bytedeco.javacv.OpenCVFrameConverter; -import org.bytedeco.opencv.global.opencv_imgcodecs; -import org.bytedeco.opencv.opencv_core.Mat; - -import jp.evosystem.objectSizeMeasurer.constants.Configurations; - -/** - * 画像内の物体の大きさを測定. - * - * @author evosystem - */ -public class ImageFileObjectSize extends AbstractObjectSize { - - /** - * main. - * - * @param args - */ - public static void main(String[] args) { - // 対象の画像ファイル - File targetImagefile = new File(Configurations.TARGET_IMAGE_FILE_PATH); - - // 対象の画像ファイルを読み込み - Mat targetImageMat = opencv_imgcodecs.imread(targetImagefile.getAbsolutePath()); - - // 画像処理 - processTargetImage(targetImageMat); - - // 画像を表示 - display(targetImageMat, "タイトル"); - } - - /** - * 画像を表示. - * - * @param image - * @param caption - */ - private static void display(Mat image, String caption) { - // コンバーターを作成 - OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); - - // 画面を作成 - CanvasFrame canvas = new CanvasFrame(caption, 1.0); - - // ウィンドウを閉じたときに終了するように設定 - canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - // フレームを表示 - canvas.showImage(converter.convert(image)); - } +package jp.evosystem.objectSizeMeasurer.mains; + +import java.io.File; + +import javax.swing.WindowConstants; + +import org.bytedeco.javacv.CanvasFrame; +import org.bytedeco.javacv.OpenCVFrameConverter; +import org.bytedeco.opencv.global.opencv_imgcodecs; +import org.bytedeco.opencv.opencv_core.Mat; + +import jp.evosystem.objectSizeMeasurer.constants.Configurations; + +/** + * 画像内の物体の大きさを測定. + * + * @author evosystem + */ +public class ImageFileObjectSize extends AbstractObjectSize { + + /** + * main. + * + * @param args + */ + public static void main(String[] args) { + // 対象の画像ファイル + File targetImagefile = new File(Configurations.TARGET_IMAGE_FILE_PATH); + + // 対象の画像ファイルを読み込み + Mat targetImageMat = opencv_imgcodecs.imread(targetImagefile.getAbsolutePath()); + + // 画像処理 + processTargetImage(targetImageMat); + + // 画像を表示 + display(targetImageMat, "タイトル"); + } + + /** + * 画像を表示. + * + * @param image + * @param caption + */ + private static void display(Mat image, String caption) { + // コンバーターを作成 + OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); + + // 画面を作成 + CanvasFrame canvas = new CanvasFrame(caption, 1.0); + + // ウィンドウを閉じたときに終了するように設定 + canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + // フレームを表示 + canvas.showImage(converter.convert(image)); + } } \ No newline at end of file diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/VideoFileObjectSize.java b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/VideoFileObjectSize.java index e090a38..e27f3cf 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/VideoFileObjectSize.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/VideoFileObjectSize.java @@ -1,93 +1,93 @@ -package jp.evosystem.objectSizeMeasurer.mains; - -import java.io.File; - -import org.bytedeco.javacv.CanvasFrame; -import org.bytedeco.javacv.FFmpegFrameGrabber; -import org.bytedeco.javacv.Frame; -import org.bytedeco.javacv.FrameGrabber; -import org.bytedeco.javacv.FrameRecorder; -import org.bytedeco.javacv.OpenCVFrameConverter; -import org.bytedeco.opencv.opencv_core.Mat; - -import jp.evosystem.objectSizeMeasurer.constants.Configurations; - -/** - * 動画内の物体の大きさを測定. - * - * @author evosystem - */ -public class VideoFileObjectSize extends AbstractObjectSize { - - /** - * main. - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 対象の動画ファイル - File targetVideofile = new File(Configurations.TARGET_VIDEO_FILE_PATH); - - // Webカメラから映像取得 - try (FrameGrabber frameGrabber = new FFmpegFrameGrabber(targetVideofile)) { - frameGrabber.start(); - - // 動画ファイルのフレームレートを取得 - double frameRate = frameGrabber.getFrameRate(); - - // レコーダーを作成 - try (FrameRecorder recorder = FrameRecorder.createDefault("target/VideoFileObjectSize.mp4", - frameGrabber.getImageWidth(), - frameGrabber.getImageHeight())) { - // 録画を開始 - if (Configurations.ENABLE_RECORDING) { - recorder.start(); - } - - // コンバーターを作成 - OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); - - // 画面を作成 - CanvasFrame canvasFrame = new CanvasFrame("タイトル", - CanvasFrame.getDefaultGamma() / frameGrabber.getGamma()); - - // 取得した映像データ - Mat grabbedImage; - - // 画面が表示中の間ループ - while (canvasFrame.isVisible() && (frameGrabber.getFrameNumber() < frameGrabber.getLengthInFrames())) { - try { - // 動画のフレームを取得 - grabbedImage = converter.convert(frameGrabber.grab()); - - // 動画のフレームが存在する場合のみ処理を実行 - if (grabbedImage != null) { - // 画像処理 - processTargetImage(grabbedImage); - - // フレームを作成 - Frame frame = converter.convert(grabbedImage); - - // フレームを表示 - canvasFrame.showImage(frame); - - // フレームを録画 - if (Configurations.ENABLE_RECORDING) { - recorder.record(frame); - } - - // フレームレートに応じて適切にウエイトを行う - Thread.sleep((int) (1000 / frameRate)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - // 画面を閉じる - canvasFrame.dispose(); - } - } - } +package jp.evosystem.objectSizeMeasurer.mains; + +import java.io.File; + +import org.bytedeco.javacv.CanvasFrame; +import org.bytedeco.javacv.FFmpegFrameGrabber; +import org.bytedeco.javacv.Frame; +import org.bytedeco.javacv.FrameGrabber; +import org.bytedeco.javacv.FrameRecorder; +import org.bytedeco.javacv.OpenCVFrameConverter; +import org.bytedeco.opencv.opencv_core.Mat; + +import jp.evosystem.objectSizeMeasurer.constants.Configurations; + +/** + * 動画内の物体の大きさを測定. + * + * @author evosystem + */ +public class VideoFileObjectSize extends AbstractObjectSize { + + /** + * main. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + // 対象の動画ファイル + File targetVideofile = new File(Configurations.TARGET_VIDEO_FILE_PATH); + + // Webカメラから映像取得 + try (FrameGrabber frameGrabber = new FFmpegFrameGrabber(targetVideofile)) { + frameGrabber.start(); + + // 動画ファイルのフレームレートを取得 + double frameRate = frameGrabber.getFrameRate(); + + // レコーダーを作成 + try (FrameRecorder recorder = FrameRecorder.createDefault("target/VideoFileObjectSize.mp4", + frameGrabber.getImageWidth(), + frameGrabber.getImageHeight())) { + // 録画を開始 + if (Configurations.ENABLE_RECORDING) { + recorder.start(); + } + + // コンバーターを作成 + OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); + + // 画面を作成 + CanvasFrame canvasFrame = new CanvasFrame("タイトル", + CanvasFrame.getDefaultGamma() / frameGrabber.getGamma()); + + // 取得した映像データ + Mat grabbedImage; + + // 画面が表示中の間ループ + while (canvasFrame.isVisible() && (frameGrabber.getFrameNumber() < frameGrabber.getLengthInFrames())) { + try { + // 動画のフレームを取得 + grabbedImage = converter.convert(frameGrabber.grab()); + + // 動画のフレームが存在する場合のみ処理を実行 + if (grabbedImage != null) { + // 画像処理 + processTargetImage(grabbedImage); + + // フレームを作成 + Frame frame = converter.convert(grabbedImage); + + // フレームを表示 + canvasFrame.showImage(frame); + + // フレームを録画 + if (Configurations.ENABLE_RECORDING) { + recorder.record(frame); + } + + // フレームレートに応じて適切にウエイトを行う + Thread.sleep((int) (1000 / frameRate)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + // 画面を閉じる + canvasFrame.dispose(); + } + } + } } \ No newline at end of file diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/WebCameraObjectSize.java b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/WebCameraObjectSize.java index 5ce9774..82e5928 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/mains/WebCameraObjectSize.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/mains/WebCameraObjectSize.java @@ -1,75 +1,75 @@ -package jp.evosystem.objectSizeMeasurer.mains; - -import org.bytedeco.javacv.CanvasFrame; -import org.bytedeco.javacv.Frame; -import org.bytedeco.javacv.FrameGrabber; -import org.bytedeco.javacv.FrameRecorder; -import org.bytedeco.javacv.OpenCVFrameConverter; -import org.bytedeco.opencv.opencv_core.Mat; - -import jp.evosystem.objectSizeMeasurer.constants.Configurations; - -/** - * Webカメラ画像から画像内の物体の大きさを測定. - * - * @author evosystem - */ -public class WebCameraObjectSize extends AbstractObjectSize { - - /** - * main. - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // Webカメラから映像取得 - try (FrameGrabber frameGrabber = FrameGrabber.createDefault(Configurations.TARGET_DEVICE_NUMBER)) { - frameGrabber.start(); - - // レコーダーを作成 - try (FrameRecorder recorder = FrameRecorder.createDefault("target/WebCameraObjectSize.mp4", - frameGrabber.getImageWidth(), - frameGrabber.getImageHeight())) { - // 録画を開始 - if (Configurations.ENABLE_RECORDING) { - recorder.start(); - } - - // コンバーターを作成 - OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); - - // 画面を作成 - CanvasFrame canvasFrame = new CanvasFrame("タイトル", - CanvasFrame.getDefaultGamma() / frameGrabber.getGamma()); - - // 取得した映像データ - Mat grabbedImage; - - // 画面が表示中の間ループ - while (canvasFrame.isVisible() && (grabbedImage = converter.convert(frameGrabber.grab())) != null) { - try { - // 画像処理 - processTargetImage(grabbedImage); - - // フレームを作成 - Frame frame = converter.convert(grabbedImage); - - // フレームを表示 - canvasFrame.showImage(frame); - - // フレームを録画 - if (Configurations.ENABLE_RECORDING) { - recorder.record(frame); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - // 画面を閉じる - canvasFrame.dispose(); - } - } - } +package jp.evosystem.objectSizeMeasurer.mains; + +import org.bytedeco.javacv.CanvasFrame; +import org.bytedeco.javacv.Frame; +import org.bytedeco.javacv.FrameGrabber; +import org.bytedeco.javacv.FrameRecorder; +import org.bytedeco.javacv.OpenCVFrameConverter; +import org.bytedeco.opencv.opencv_core.Mat; + +import jp.evosystem.objectSizeMeasurer.constants.Configurations; + +/** + * Webカメラ画像から画像内の物体の大きさを測定. + * + * @author evosystem + */ +public class WebCameraObjectSize extends AbstractObjectSize { + + /** + * main. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + // Webカメラから映像取得 + try (FrameGrabber frameGrabber = FrameGrabber.createDefault(Configurations.TARGET_DEVICE_NUMBER)) { + frameGrabber.start(); + + // レコーダーを作成 + try (FrameRecorder recorder = FrameRecorder.createDefault("target/WebCameraObjectSize.mp4", + frameGrabber.getImageWidth(), + frameGrabber.getImageHeight())) { + // 録画を開始 + if (Configurations.ENABLE_RECORDING) { + recorder.start(); + } + + // コンバーターを作成 + OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); + + // 画面を作成 + CanvasFrame canvasFrame = new CanvasFrame("タイトル", + CanvasFrame.getDefaultGamma() / frameGrabber.getGamma()); + + // 取得した映像データ + Mat grabbedImage; + + // 画面が表示中の間ループ + while (canvasFrame.isVisible() && (grabbedImage = converter.convert(frameGrabber.grab())) != null) { + try { + // 画像処理 + processTargetImage(grabbedImage); + + // フレームを作成 + Frame frame = converter.convert(grabbedImage); + + // フレームを表示 + canvasFrame.showImage(frame); + + // フレームを録画 + if (Configurations.ENABLE_RECORDING) { + recorder.record(frame); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + // 画面を閉じる + canvasFrame.dispose(); + } + } + } } \ No newline at end of file diff --git a/src/main/java/jp/evosystem/objectSizeMeasurer/utils/MathHelper.java b/src/main/java/jp/evosystem/objectSizeMeasurer/utils/MathHelper.java index 7907331..ce60a4e 100644 --- a/src/main/java/jp/evosystem/objectSizeMeasurer/utils/MathHelper.java +++ b/src/main/java/jp/evosystem/objectSizeMeasurer/utils/MathHelper.java @@ -1,109 +1,109 @@ -package jp.evosystem.objectSizeMeasurer.utils; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import org.bytedeco.opencv.opencv_core.Point; - -/** - * 計算ヘルパー. - * - * @author evosystem - */ -public class MathHelper { - - /** - * 2点間の中間点を計算. - * - * @param point1 - * @param point2 - * @return - */ - public static Point midPoint(Point point1, Point point2) { - return new Point((point1.x() + point2.x()) / 2, (point1.y() + point2.y()) / 2); - } - - /** - * 2点間のユークリッド距離を計算. - * - * @param point1 - * @param point2 - * @return - */ - public static double distance(Point point1, Point point2) { - double deltaX = point1.x() - point2.x(); - double deltaY = point1.y() - point2.y(); - double result = Math.sqrt(deltaX * deltaX + deltaY * deltaY); - return result; - } - - /** - * 4点の座標を並び替え.
- * tl,tr,br,blの順.
- * - * @see MathHelper#orderPoints2 - * @see Ordering - * coordinates clockwise with Python and OpenCV - * @param pointList - * @return - * @deprecated {@link MathHelper#orderPoints2}を使用してください. - */ - @Deprecated - public static List orderPoints(List pointList) { - Point tl = null; - Point tr = null; - Point br = null; - Point bl = null; - - double min = Double.POSITIVE_INFINITY; - double max = Double.NEGATIVE_INFINITY; - for (Point point : pointList) { - double sum = point.x() + point.y(); - if (sum < min) { - min = sum; - tl = point; - } - if (max < sum) { - max = sum; - br = point; - } - } - - min = Double.POSITIVE_INFINITY; - max = Double.NEGATIVE_INFINITY; - for (Point point : pointList) { - double diff = point.y() - point.x(); - if (diff < min) { - min = diff; - tr = point; - } - if (max < diff) { - max = diff; - bl = point; - } - } - - return Arrays.asList(tl, tr, br, bl); - } - - /** - * 4点の座標を並び替え.
- * tl,tr,br,blの順. - * - * @see MathHelper#orderPoints - * @see Ordering - * coordinates clockwise with Python and OpenCV - * @param pointList - * @return - */ - public static List orderPoints2(List pointList) { - Point tl = pointList.stream().min(Comparator.comparingInt(point -> point.x() + point.y())).get(); - Point tr = pointList.stream().min(Comparator.comparingInt(point -> point.y() - point.x())).get(); - Point br = pointList.stream().max(Comparator.comparingInt(point -> point.x() + point.y())).get(); - Point bl = pointList.stream().max(Comparator.comparingInt(point -> point.y() - point.x())).get(); - return Arrays.asList(tl, tr, br, bl); - } +package jp.evosystem.objectSizeMeasurer.utils; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.bytedeco.opencv.opencv_core.Point; + +/** + * 計算ヘルパー. + * + * @author evosystem + */ +public class MathHelper { + + /** + * 2点間の中間点を計算. + * + * @param point1 + * @param point2 + * @return + */ + public static Point midPoint(Point point1, Point point2) { + return new Point((point1.x() + point2.x()) / 2, (point1.y() + point2.y()) / 2); + } + + /** + * 2点間のユークリッド距離を計算. + * + * @param point1 + * @param point2 + * @return + */ + public static double distance(Point point1, Point point2) { + double deltaX = point1.x() - point2.x(); + double deltaY = point1.y() - point2.y(); + double result = Math.sqrt(deltaX * deltaX + deltaY * deltaY); + return result; + } + + /** + * 4点の座標を並び替え.
+ * tl,tr,br,blの順.
+ * + * @see MathHelper#orderPoints2 + * @see Ordering + * coordinates clockwise with Python and OpenCV + * @param pointList + * @return + * @deprecated {@link MathHelper#orderPoints2}を使用してください. + */ + @Deprecated + public static List orderPoints(List pointList) { + Point tl = null; + Point tr = null; + Point br = null; + Point bl = null; + + double min = Double.POSITIVE_INFINITY; + double max = Double.NEGATIVE_INFINITY; + for (Point point : pointList) { + double sum = point.x() + point.y(); + if (sum < min) { + min = sum; + tl = point; + } + if (max < sum) { + max = sum; + br = point; + } + } + + min = Double.POSITIVE_INFINITY; + max = Double.NEGATIVE_INFINITY; + for (Point point : pointList) { + double diff = point.y() - point.x(); + if (diff < min) { + min = diff; + tr = point; + } + if (max < diff) { + max = diff; + bl = point; + } + } + + return Arrays.asList(tl, tr, br, bl); + } + + /** + * 4点の座標を並び替え.
+ * tl,tr,br,blの順. + * + * @see MathHelper#orderPoints + * @see Ordering + * coordinates clockwise with Python and OpenCV + * @param pointList + * @return + */ + public static List orderPoints2(List pointList) { + Point tl = pointList.stream().min(Comparator.comparingInt(point -> point.x() + point.y())).get(); + Point tr = pointList.stream().min(Comparator.comparingInt(point -> point.y() - point.x())).get(); + Point br = pointList.stream().max(Comparator.comparingInt(point -> point.x() + point.y())).get(); + Point bl = pointList.stream().max(Comparator.comparingInt(point -> point.y() - point.x())).get(); + return Arrays.asList(tl, tr, br, bl); + } } \ No newline at end of file