@yuuki_0551

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[Swift + OpenCV] signal SIGABRTエラー

解決したいこと

OpenCVを用いて輪郭抽出のコードを作成しています.
下記のコードを作成し実行したところ,シミュレーターは起動するのですが,ボタン(change img)をタップしたところ,エラーが発生しました.
解決方法を教えてください.

発生している問題・エラー

Thread 1: signal SIGABRT

該当するソースコード

import SwiftUI
import opencv2

struct ContentView: View {
    @State var img:UIImage? = nil
    var body: some View {
        if let img = img {
            Image(uiImage: img)
                .resizable()
                .scaledToFit()
        }
        Button(action: {
            let readImg = UIImage(named: "001")
            let src = Mat(uiImage: readImg!)
            // グレースケール
            let dstGray = Mat()
            Imgproc.cvtColor(src: src, dst: dstGray, code: ColorConversionCodes.COLOR_RGB2GRAY)
            // 平滑化
            let dstBlur = Mat()
            Imgproc.blur(src: dstGray, dst: dstBlur, ksize: Size2i(width: 9, height: 9))
            // 二値化
            let dstThresh = Mat()
            Imgproc.threshold(src: dstBlur, dst: dstThresh, thresh: 100, maxval: 255, type: ThresholdTypes.THRESH_OTSU)
            //エッジ検出
            let dstCanny = Mat()
            Imgproc.Canny(image: dstThresh, edges: dstCanny, threshold1: 10, threshold2: 360)
            // 輪郭の取得
            let dstLine = Mat()
            let contours: NSMutableArray = []
            Imgproc.findContours(image: dstCanny, contours: contours, hierarchy: dstLine, mode: RetrievalModes.RETR_EXTERNAL, method: ContourApproximationModes.CHAIN_APPROX_SIMPLE)
            // 型のキャスト
            let contoursp2i = contours as! [[Point2i]]
            // 輪郭の描画
            for _ in 0..<contours.count {
                let area = Imgproc.contourArea(contour: dstLine)
                if area > 1000 {
                    Imgproc.drawContours(image: src, contours: contoursp2i, contourIdx: -1, color: Scalar(255, 0, 0, 255), thickness: 20)
                }
            }
            img = src.toUIImage()
            print (contours.count)
        }){
            Text("change img")
        }
    }
}
 
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

自分で試したこと

クリーンして再ビルドなど,基本的なことは試しました.
また,エラー文を検索しましたが,解決に至りませんでした.

環境

macOS 14.1.2
Xcode 15.0.1

1 likes

1Answer

理由は分かりませんが、輪郭の描画のところのImgproc.contourArea(contour: dstLine)をなくすと、落ちなくなりました。
つまり、以下のように変更します。

変更前
// 輪郭の描画
for _ in 0..<contours.count {
    let area = Imgproc.contourArea(contour: dstLine)
    if area > 1000 {
        Imgproc.drawContours(image: src, contours: contoursp2i, contourIdx: -1, color: Scalar(255, 0, 0, 255), thickness: 20)
    }
}
変更後
// 輪郭の描画
Imgproc.drawContours(image: src, contours: contoursp2i, contourIdx: -1, color: Scalar(255, 0, 0, 255), thickness: 20)
0Like

Comments

  1. @yuuki_0551

    Questioner

    コメント頂きありがとうございます。
    私も試したところ、確かに落ちなくなりました。ありがとうございます。
    しかし、このままでは細かな集合も全て拾ってしまうことになり、正確な輪郭の抽出が難しくなってしまいます。
    なにか打開策をいただけると助かります。

  2. Imgproc.drawContours(image: src, contours: contoursp2i, contourIdx: -1, color: Scalar(255, 0, 0, 255), thickness: 20)

    最後の引数の20は線の太さです。ここを、12に変更してはどうですか?

  3. 間引かないのが、一番正確な輪郭だと思いますが、
    例えば、以下のように変更すると、$\frac{1}{N}$に間引きます。

      // 型のキャスト
    - let contoursp2i = contours as! [[Point2i]]
    + let N: Int = 5
    + let contoursp2i = (contours as! [[Point2i]]).enumerated().filter { $0.offset % N == 0 }.map { $0.element }
    
  4. @yuuki_0551

    Questioner

    確かめてみます.
    ご教示いただきありがとうございます.

Your answer might help someone💌