0

I'm new to android development. I'm trying to utilize a code that I found (thanks to @micfra) that should do what I want, which is:

  • Load main image
  • Load template image
  • Find the location of the small image on the main image one using OpenCV matchTemplate function
  • Draw the rectangle around the location found and write a result in the file.

I heve set up my working environiment fine, installed OpenCV libaries, NDK, SDK, ADT. I have created a simple Android app, placed the images into the res folder and eddited the MainActivity.java file to look like this:

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);


    }
}

When I try to execute the application on the mobile phone, it only executes for few seconds and then terminates with "unexpected stop". I know, it doesn't give a lot of info about the error, but the code compile with no errors and I'm not sure where to start. As I mentioned, I'm totally new to Android and Java and any help would be appreciated.

--------**----------- UPDATED

This is the output of the LogCat when trying to run the app

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
jaspernorth
  • 415
  • 1
  • 10
  • 28
  • Is there any log output associated with the "unexpected stop"? If so, it would be helpful if you posted it. – Aurelius Jul 08 '13 at 17:36
  • I have only LogCat output – jaspernorth Jul 08 '13 at 21:31
  • The error is stated in this line: `01-02 03:25:53.180: W/dalvikvm(20500): No implementation found for native Lorg/opencv/highgui/Highgui;.imread_1 (Ljava/lang/String;)J` I think [this question](http://stackoverflow.com/questions/11939192/unsatisfied-link-error-opencv-for-android-non-native) is identical to yours. – Aurelius Jul 08 '13 at 21:38

1 Answers1

0

Sending .bmp file as argument in run method which is having String as it argument causes the problem, instead of doing this You can achieve the same thing as

change the run method as :

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

and replace the following 2 lines

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

and use this

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

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

now, put all bmp images in drawable folder and make the call to run as

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

This is working fine for me, and i m sure it will work fine for you

Mehul Thakkar
  • 12,440
  • 10
  • 52
  • 81