I am creating an app in android studio that uses library opencv and yolo. I want to store the yolo config file and weights inside the android package. Right now I have those file in the external storage of my phone and I access them like this:
String yoloCfg = Environment.getExternalStorageDirectory() + "/dnns/traffic-yolov3-tiny.cfg" ;
String yoloWeights = Environment.getExternalStorageDirectory() + "/dnns/traffic-yolov3-tiny_15000.weights";
yolo = Dnn.readNetFromDarknet(yoloCfg, yoloWeights);
My question is: where do I put yolo config file and weights for them to be inside the app when the user downloads the apk and how do I get the path to them, since readNetFromDarknet needs as args the path of those files.
I have tried put them in the asset and attempt to get the path to asset but it doesnt work. This is the code I tried:
String yoloCfg = "file:///android_asset/traffic-yolov3-tiny.cfg";
String yoloWeights = "file:///android_asset/traffic-yolov3-tiny_15000.weights";
yolo = Dnn.readNetFromDarknet(yoloCfg, yoloWeights);
This is where I have the files:
Location of files
And this is the error I get:
E/cv::error(): OpenCV(4.0.1) Error: Parsing error (Failed to parse NetParameter file: file:///android_asset/traffic-yolov3-tiny.cfg) in readNetFromDarknet, file /build/master_pack-android/opencv/modules/dnn/src/darknet/darknet_importer.cpp, line 207
E/org.opencv.dnn: dnn::readNetFromDarknet_10() caught cv::Exception: OpenCV(4.0.1) /build/master_pack-android/opencv/modules/dnn/src/darknet/darknet_importer.cpp:207: error: (-212:Parsing error) Failed to parse NetParameter file: file:///android_asset/traffic-yolov3-tiny.cfg in function 'readNetFromDarknet'
E/SurfaceView: Exception configuring surface
I had the exact same issue. What I did to fix this was to add the files in the asset folder; then I created two files and copied the content of the asset folder files there.
Make sure to use the following path and create your files there:
applicationContext.filesDir.absolutePath
Related
I am making an app which use the following java line:
Net dnnNet = Dnn.readNetFromONNX("path\to\file");
As you can see, readNetFromONNX requires path to onnx file.
So I put my onnx file under assest folder, so I can use it at run time.
The problem is I you can only read assets foler with AssestManager and inputstream... the readNetFromONNX needs path...
How do I overcome this probelm? Is there a way to get the path of the file at run time? Maybe other folder?
Thanks from advance
I'm developing an android application that uses OpenCV C++ dll(.so file) in Unity.
The C++ dll accesses a cascade file to use OpenCV functions.
*C++ DLL side code
cv::String face_cascade_name = "haarcascade_frontalface_alt.xml";
if (!face_cascade.load(face_cascade_name)) {
printf("--(!)Error loading face cascade, please change face_cascade_name in source code.\n");
return -1;
};
However If I build an android application in Unity and install the app on Android device, it fails to load the xml file.
How can I access the cascade xml in C++ DLL in Android apk?
*If I put the xml to assets/StreamingAssets in Unity, the xml file exists in myapp.apk/assets folder.
Android is a special case since the StreamingAssets folder is compressed and unusable by the OpenCV file reader. You have to 1) copy the file from your StreamingAssets folder to the persistent data path (there's documentation on how to copy and write files in the unity manual), 2) fetch the name of that file using Application.persistantDataPath, like:
string cascadeFileName = (Application.persistentDataPath + "/" + fileName);
This question already has answers here:
How To Get File In Assets From Android NDK
(2 answers)
Opening a File from assets folder in android
(6 answers)
Closed 8 years ago.
I wrote a small test application that uses SDL2 on Android via the NDK. It compiles and runs. However, as soon as I try to open files I get FileNotFound Exceptions. I added an assets Directory in my eclipse workdir and put files inside it. When I Export the projekt to an .apk, I can open the file in 7z and see that there is an assets Directory with those files in it. However, when the code gets executed and I try to open assets/somefile.txt, I get a FileNotFound Exception.
Google so far told me that I could put an sdcard in my device with those files on it and access it through /sdcard/ . I'ld like to include those files in my apk though.
How do I Access the files I put in assets ? Or where should I put those files and how should I adjust my path it can Access them at runtime?
Place this code before anything else in your main activity ->
if (Environment.getExternalStorageState (). equals (Environment.MEDIA_MOUNTED)) {
File directory = new File (Environment.getExternalStorageDirectory () + + File.separator "YourFolderName");
directory.mkdirs ();
}
Give this permission in the Manifest xml ->
<uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
This code works in the simulator but not on my Android device:
local path = system.pathForFile("chinese_rules.db")
print("PATH:: " .. tostring( path ) )
When I run this code on my Galaxy S4 path returns nil.
My first thought was that it was some typo (case sensitivity) but I can't find any typo:
http://i59.tinypic.com/wlpu14.png
I can't find any reason why it should receive nil. This causes a problem as I can't load my database.
I have also tried this with the same result:
local path = system.pathForFile("chinese_rules.db", system.ResourceDirectory)
I have been able to load a path and load databases like this before.
Corona Build: 2013.2100 (2013.12.7)
Further reading the documentation I don't see that .db is a restricted file type:
Corona allows direct loading of images and audio files using the
appropriate APIs, but it has limited access to resource files on
Android using the file I/O APIs. Specifically, the following types can
not be read from the resources directory: .html, .htm., .3gp, .m4v,
.mp4,.png, .jpg, and .ttf.
http://docs.coronalabs.com/api/library/system/pathForFile.html
I found out the reason for the problem:
We are two that are working on this project and he had setup to use expansion files so two files was created (the main APK and the OBB expansion file) which I didn't notice and I only loaded the main APK file and I guess the database is in the OBB file. After setting not to use an expansion file the app works.
usesExpansionFile = false
I'm developing an android library project that should read from an xml file in its raw resources (let's call it xml_file_name.myextension).
What I do is basically creating a jar file of the library project including these folders:
src
gen
lib
res/raw
and referencing it as a library in a test app. This is the code that I use (inside the library project) in order to get the xml file:
int xml_res_id = -1;
for (Field f : R.raw.class.getFields()) {
System.out.println("Raw resource found: " + f.getName());
if (f.getName().equalsIgnoreCase("xml_file_name"))
xml_res_id = f.getInt(null);
}
if(xml_res_id != -1){
System.out.println("xml_file_id: " + xml_res_id);
InputStream is = context.getResources().openRawResource(xml_res_id);
// Decode xml file with SAXParser..
}
(I have the app context because the app explicitly passes it to the library project.)
What happens is that when I launch the test app (and call the method that reads the xml file) I get this error:
It seems that the xml file is actually in the right folder, because:
1) The for loop actually prints "Raw resource found: xml_file_name.myextension" and "xml_file_id: 2130968576"
2) If I put a file named "xml_file_name.myextension" in the res/raw folder of the app, it does not compile, and the error is: "Error generating final archive: Found duplicate file for APK: res/raw/xml_file_name.myextension". This basically gives me the proof that the
file is correctly "imported" from the library project.
Please Note:
I also tried in this other way
InputStream is = context.getResources().openRawResource(R.raw.xml_file_name);
getting the same error.
I honestly don't understand what could be the problem.. what am I doing wrong?
Edit:
for anyone interested in this issue:
I finally realized that this is not possible, basically because when I try to get a resource through context.anymethod I refer to the R file of the app, so I can't give the resource ID got from the R file of my library project.
It will compile, because the library project jar file contains the resource (R.raw.xml_file), but the call to context.something will always give null as a result because it refers to the app R file, that does not have that particular resource in it.
I finally had to put my xml file in the res/raw folder of the app, and access the xml_file raw resource in this way:
int xml_id = context.getResources().getIdentifier("xml_file_name", "raw", context.getPackageName());
// Getting input stream from xml file
InputStream is = context.getResources().openRawResource(xml_id);
I have actually done this with success - the library object should be within the app context. However, it only works with Activity and no other type that I have found. Using the same library with a FragmentActivity fails with NoClassDefFoundError.
EDIT****
It may work with a FragmentActivity within the same root namespace as the library. I was accessing from a different root namespace.
END EDIT****
I have a library project that references an xml file:
InputStream is = context.getResources().openRawResource(R.raw.application_table_defs);
when I call the library method that executes the previous line I have to pass in a context:
Context context = this.getContext();
The key is fully qualifying the getResource to context.getResources()... that was injected.