簡體   English   中英

無法在Android設備上執行OpenCV模板匹配

[英]Unable to execute OpenCV template matching on Android device

我是android開發的新手。 我正在嘗試利用我發現的代碼(由於@micfra)來完成我想要的工作,這是:

  • 載入主圖
  • 加載模板圖片
  • 使用OpenCV matchTemplate函數在主圖像上找到小圖像的位置
  • 在找到的位置周圍繪制矩形,然后將結果寫入文件中。

我已經設置好我的工作環境,安裝了OpenCV庫,NDK,SDK,ADT。 我創建了一個簡單的Android應用,將圖像放入res文件夾,並編輯MainActivity.java文件,如下所示:

package com.example.match;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        run("bmp1.bmp", "bmp2.bmp", "bmp3.bmp", Imgproc.TM_CCOEFF);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }




        public void run(String inFile, String templateFile, String outFile, int match_method) {
            System.out.println("\nRunning Template Matching");

            Mat img = Highgui.imread(inFile);
            Mat templ = Highgui.imread(templateFile);

            // / Create the result matrix
            int result_cols = img.cols() - templ.cols() + 1;
            int result_rows = img.rows() - templ.rows() + 1;
            Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

            // / Do the Matching and Normalize
            Imgproc.matchTemplate(img, templ, result, match_method);
            Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

            // / Localizing the best match with minMaxLoc
            MinMaxLocResult mmr = Core.minMaxLoc(result);

            Point matchLoc;
            if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
                matchLoc = mmr.minLoc;
            } else {
                matchLoc = mmr.maxLoc;
            }

            // / Show me what you got
            Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
                    matchLoc.y + templ.rows()), new Scalar(0, 255, 0));

            // Save the visualized detection.
            System.out.println("Writing "+ outFile);
            Highgui.imwrite(outFile, img);


    }
}

當我嘗試在手機上執行該應用程序時,它僅執行幾秒鍾,然后以“意外停止”終止。 我知道,它沒有提供有關該錯誤的很多信息,但是代碼編譯時沒有錯誤,而且我不確定從哪里開始。 正如我提到的,我是Android和Java的新手,任何幫助將不勝感激。

-------- * * -----------更新

這是嘗試運行應用程序時LogCat的輸出

01-02 03:25:51.055: I/StatusBarPolicy(2802): BAT. S:5 H:2
01-02 03:25:52.474: D/KeyguardViewMediator(2690): handleTimeout
01-02 03:25:52.770: D/AndroidRuntime(20485): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
01-02 03:25:52.770: D/AndroidRuntime(20485): CheckJNI is OFF
01-02 03:25:52.770: D/AndroidRuntime(20485): setted country_code = UK
01-02 03:25:52.770: D/AndroidRuntime(20485): setted sales_code = O2U
01-02 03:25:52.770: D/AndroidRuntime(20485): found sales_code tag = <O2U>, </O2U> 
01-02 03:25:52.770: D/dalvikvm(20485): creating instr width table
01-02 03:25:52.850: D/LibQmg_native(20485): register_android_app_LibQmg
01-02 03:25:52.850: D/DeviceEncryption(20485): JNI: register_android_deviceencryption_DeviceEncryptionManager
01-02 03:25:52.875: D/AndroidRuntime(20485): Calling main entry com.android.commands.pm.Pm
01-02 03:25:52.875: D/AndroidRuntime(20485): Shutting down VM
01-02 03:25:52.880: D/dalvikvm(20485): GC_CONCURRENT freed 104K, 69% free 317K/1024K, external 0K/0K, paused 0ms+1ms
01-02 03:25:52.880: D/dalvikvm(20485): Debugger has detached; object registry had 1 entries
01-02 03:25:52.970: D/AndroidRuntime(20493): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
01-02 03:25:52.970: D/AndroidRuntime(20493): CheckJNI is OFF
01-02 03:25:52.970: D/AndroidRuntime(20493): setted country_code = UK
01-02 03:25:52.970: D/AndroidRuntime(20493): setted sales_code = O2U
01-02 03:25:52.970: D/AndroidRuntime(20493): found sales_code tag = <O2U>, </O2U> 
01-02 03:25:52.970: D/dalvikvm(20493): creating instr width table
01-02 03:25:53.035: D/LibQmg_native(20493): register_android_app_LibQmg
01-02 03:25:53.040: D/DeviceEncryption(20493): JNI: register_android_deviceencryption_DeviceEncryptionManager
01-02 03:25:53.060: D/AndroidRuntime(20493): Calling main entry com.android.commands.am.Am
01-02 03:25:53.065: I/ActivityManager(2690): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.match/.MainActivity } from pid 20493
01-02 03:25:53.070: V/LauncherAppWidgetHostView(2851): dispatchSaveInstanceState: widgetid=2 vid=-1
01-02 03:25:53.070: V/LauncherAppWidgetHostView(2851): dispatchSaveInstanceState: widgetid=1 vid=-1
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:303 [0:0] onReceive()@@@ sec.android.intent.action.HOME_PAUSE
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:39 [0:0] AccuWeatherClockWidgetID_Length
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:40 [0:0] getPrefIDs() : length = 1
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:46 [0:0] getPrefIDs() : Ids1 = 2
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1511 [0:0] disable handler
01-02 03:25:53.075: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1513 [0:0] handler not null
01-02 03:25:53.095: I/ActivityManager(2690): Start proc com.example.match for activity com.example.match/.MainActivity: pid=20500 uid=10105 gids={}
01-02 03:25:53.100: D/PhotoAppWidgetProvider(4911): OnReceive Start
01-02 03:25:53.100: D/PhotoAppWidgetProvider(4911): PauseSlideShow Start
01-02 03:25:53.100: D/CalendarAppWidgetProviderAgenda(5097): ACTION_HOME_PAUSE: false
01-02 03:25:53.105: D/AndroidRuntime(20493): Shutting down VM
01-02 03:25:53.105: D/dalvikvm(20493): GC_CONCURRENT freed 105K, 67% free 343K/1024K, external 0K/0K, paused 0ms+0ms
01-02 03:25:53.105: D/jdwp(20493): Got wake-up signal, bailing out of select
01-02 03:25:53.105: D/dalvikvm(20493): Debugger has detached; object registry had 1 entries
01-02 03:25:53.135: I/OrientationDebug(2690): [pwm] in updateOrientationListenerLp()
01-02 03:25:53.135: V/OrientationDebug(2690): in updateOrientationListenerLp(), Screen status=true, current orientation=-1, SensorEnabled=true
01-02 03:25:53.135: I/OrientationDebug(2690): [pwm] needSensorRunningLp(), return true #4
01-02 03:25:53.140: D/dalvikvm(20500): Debugger has detached; object registry had 1 entries
01-02 03:25:53.175: D/dalvikvm(20500): GC_EXTERNAL_ALLOC freed 45K, 54% free 2521K/5379K, external 0K/0K, paused 18ms
01-02 03:25:53.180: I/System.out(20500): Running Template Matching
01-02 03:25:53.180: W/dalvikvm(20500): No implementation found for native Lorg/opencv/highgui/Highgui;.imread_1 (Ljava/lang/String;)J
01-02 03:25:53.185: D/AndroidRuntime(20500): Shutting down VM
01-02 03:25:53.185: W/dalvikvm(20500): threadid=1: thread exiting with uncaught exception (group=0x40015578)
01-02 03:25:53.185: E/(2690): Dumpstate > /data/log/dumpstate_app_error
01-02 03:25:53.185: E/AndroidRuntime(20500): FATAL EXCEPTION: main
01-02 03:25:53.185: E/AndroidRuntime(20500): java.lang.UnsatisfiedLinkError: imread_1
01-02 03:25:53.185: E/AndroidRuntime(20500):    at org.opencv.highgui.Highgui.imread_1(Native Method)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at org.opencv.highgui.Highgui.imread(Highgui.java:352)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at com.example.match.MainActivity.run(MainActivity.java:39)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at com.example.match.MainActivity.onCreate(MainActivity.java:23)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.os.Looper.loop(Looper.java:123)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at android.app.ActivityThread.main(ActivityThread.java:3691)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at java.lang.reflect.Method.invokeNative(Native Method)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at java.lang.reflect.Method.invoke(Method.java:507)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
01-02 03:25:53.185: E/AndroidRuntime(20500):    at dalvik.system.NativeStart.main(Native Method)
01-02 03:25:53.185: W/ActivityManager(2690):   Force finishing activity com.example.match/.MainActivity
01-02 03:25:53.190: I/dumpstate(20513): begin
01-02 03:25:53.285: I/Launcher(2851): onWindowFocusChanged(false)
01-02 03:25:53.690: W/ActivityManager(2690): Activity pause timeout for HistoryRecord{40540a68 com.example.match/.MainActivity}
01-02 03:25:56.615: D/VoldCmdListener(2566): asec list
01-02 03:25:57.645: I/dumpstate(20513): done
01-02 03:25:57.775: D/dalvikvm(2690): GC_EXTERNAL_ALLOC freed 360K, 41% free 6992K/11847K, external 5334K/5666K, paused 75ms
01-02 03:25:57.805: I/OrientationDebug(2690): [pwm] in updateOrientationListenerLp()
01-02 03:25:57.805: V/OrientationDebug(2690): in updateOrientationListenerLp(), Screen status=true, current orientation=1, SensorEnabled=true
01-02 03:25:57.805: I/OrientationDebug(2690): [pwm] needSensorRunningLp(), return true #4
01-02 03:25:57.810: I/Launcher(2851): onResume(). mIsNewIntent : false screenOff: false
01-02 03:25:57.820: I/WindowOrientationListener(2690): orientation 70.307526 gives new rotation = 1
01-02 03:25:57.820: I/OrientationDebug(2690): [pwm] in MyOrientationListener.onOrientationChanged() rotation=1  mFancyRotationAnimation=0   now call mWindowManager.setRotation()
01-02 03:25:57.820: I/OrientationDebug(2690): [wms] in setRotation() rotation=1 alwaysSendConfiguration=false animFlags=0
01-02 03:25:57.820: I/OrientationDebug(2690): [wms] in setRotation() now call setRotationUnchecked()
01-02 03:25:57.820: I/WindowOrientationListener(2690): orientation 70.307526 gives new rotation = 1
01-02 03:25:57.825: I/(2851): !@Mali Android API Version : 7 [946783557]
01-02 03:25:57.830: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:303 [0:0] onReceive()@@@ sec.android.intent.action.HOME_RESUME
01-02 03:25:57.830: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:39 [0:0] AccuWeatherClockWidgetID_Length
01-02 03:25:57.830: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:40 [0:0] getPrefIDs() : length = 1
01-02 03:25:57.830: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:46 [0:0] getPrefIDs() : Ids1 = 2
01-02 03:25:57.855: D/PhotoAppWidgetProvider(4911): OnReceive Start
01-02 03:25:57.855: D/PhotoAppWidgetProvider(4911): RestartSlideShow Start
01-02 03:25:57.875: D/Buddies--------------------------->(4933): Service:OnReceive ACTION_HOME_RESUME called
01-02 03:25:58.020: D/dalvikvm(2851): GC_EXTERNAL_ALLOC freed 272K, 52% free 3582K/7367K, external 10859K/10884K, paused 28ms
01-02 03:25:58.030: D/GLCanvas(2851): start render to texture
01-02 03:25:58.030: D/GLCanvas(2851): start render to texture
01-02 03:25:58.115: D/GLCanvas(2851): start render to texture
01-02 03:25:58.120: D/GLCanvas(2851): start render to texture
01-02 03:25:58.120: D/GLCanvas(2851): start render to texture
01-02 03:25:58.120: D/GLCanvas(2851): start render to texture
01-02 03:25:58.185: D/GLCanvas(2851): start render to texture
01-02 03:25:58.190: D/GLCanvas(2851): start render to texture
01-02 03:25:58.190: D/GLCanvas(2851): start render to texture
01-02 03:25:58.190: D/GLCanvas(2851): start render to texture
01-02 03:25:58.200: D/GLCanvas(2851): start render to texture
01-02 03:25:58.200: D/GLCanvas(2851): start render to texture
01-02 03:25:58.295: D/dalvikvm(2851): GC_EXTERNAL_ALLOC freed 170K, 53% free 3511K/7367K, external 10703K/10721K, paused 27ms
01-02 03:25:58.300: D/GLCanvas(2851): start render to texture
01-02 03:25:58.300: D/GLCanvas(2851): start render to texture
01-02 03:25:58.305: D/GLCanvas(2851): start render to texture
01-02 03:25:58.305: D/GLCanvas(2851): start render to texture
01-02 03:26:07.850: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1523 [0:0] Handler:{ what=101 when=-7ms }
01-02 03:26:07.890: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1535 [0:0] HANDLER_EVENT_WEATHER_SCROLL : 1
01-02 03:26:07.955: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:39 [0:0] AccuWeatherClockWidgetID_Length
01-02 03:26:07.955: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:40 [0:0] getPrefIDs() : length = 1
01-02 03:26:07.955: E/com.samsung.app(4647): [MSC]>>> WidgetIdManager.java:46 [0:0] getPrefIDs() : Ids1 = 2
01-02 03:26:07.955: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1005 [0:0] setWeaterData 2 2130903087 true
01-02 03:26:07.955: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1013 [0:0] setWeatherData dbhelper!=null
01-02 03:26:07.965: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1015 [0:0] mWeatherCount : 2
01-02 03:26:07.965: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1027 [0:0] onReceive Lincoln cityId:329125
01-02 03:26:07.965: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1027 [0:0] onReceive Nottingham cityId:330088
01-02 03:26:07.980: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1631 [0:0] @@@@@ mainLayoutId--> :3
01-02 03:26:08.000: E/com.samsung.app(4647): [MSC]>>> WeatherWidgetProvider.java:1264 [0:0] =========2
01-02 03:26:08.305: W/ActivityManager(2690): Activity destroy timeout for HistoryRecord{40540a68 com.example.match/.MainActivity}
01-02 03:26:10.564: W/PowerManagerService(2690): Timer 0x3->0x1|0x0
01-02 03:26:10.564: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 112
01-02 03:26:10.564: I/PowerManagerService(2690): Ulight 3->1|0
01-02 03:26:10.579: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 107
01-02 03:26:10.594: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 101
01-02 03:26:10.614: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 96
01-02 03:26:10.630: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 90
01-02 03:26:10.645: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 85
01-02 03:26:10.660: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 79
01-02 03:26:10.680: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 74
01-02 03:26:10.695: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 69
01-02 03:26:10.710: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 63
01-02 03:26:10.725: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 58
01-02 03:26:10.740: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 52
01-02 03:26:10.755: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 47
01-02 03:26:10.775: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 41
01-02 03:26:10.790: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 36
01-02 03:26:10.805: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 30
01-02 03:26:10.820: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 25
01-02 03:26:10.835: E/lights(2690): write_int: path /sys/class/backlight/pwm-backlight/brightness, value 20
01-02 03:26:10.840: I/PowerManagerService(2690): Light Animator Finished curIntValue=20

在具有String作為其參數的run方法中將.bmp文件作為參數發送會導致問題,而不是這樣做,您可以實現與

將運行方法更改為:

    public void run(int inFile, int templateFile, String outFile, int match_method)

並替換以下兩行

    Mat img = Highgui.imread(inFile);
    Mat templ = Highgui.imread(templateFile);

並使用這個

    Mat img = new Mat();
    Mat templ= new Mat();

    try {
        img= Utils.loadResource(this, inFile);
        templ= Utils.loadResource(this, templateFile);
    } catch (IOException e) {
        e.printStackTrace();
    }

現在,將所有bmp圖像放置在drawable文件夾中,並以如下方式運行

   run(R.drawable.bmp1, R.drawable.bmp2, R.drawable.bmp3, Imgproc.TM_CCOEFF);

這對我來說很好,我確定它將對您很好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM