Using OpenCV FileStorage on iOS - c++

I am creating an object classifier using OpenCV and to avoid having to train the classifiers every time the app is launched I would like to somehow store them in a file. The most convenient way available seems to be using OpenCVs FileStorage class.
I gave this a shot but it didn't seem to work. The saved file did not show up anywhere though I did not receive an error. I suppose iOS doesn't just let you save any file. An alternative way would be to retrieve the YAML as a string, convert it to an NSString and save it in a property list, but I am not sure how this can be done or whether it is even possible.
Any help would be greatly appreciated.

I managed to get the FileStorage class working with iOS. The problem was that I needed to make sure the file was being created in iOSs designated Documents Directory. Here is some sample code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *vocabPath = [docs stringByAppendingPathComponent:#"vocabulary.xml"];
FileStorage fs([vocabPath UTF8String], FileStorage::WRITE);
// vocab is a CvMat object representing the vocabulary in my bag of features model
fs << "vocabulary" << vocab;
fs.release();
// READING
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *vocabPath = [docs stringByAppendingPathComponent:#"vocabulary.xml"];
FileStorage fs([vocabPath UTF8String], FileStorage::READ);
// vocab is a CvMat object representing the vocabulary in my bag of features model
fs["vocabulary"] >> vocab;
fs.release();

Related

How to skip unsupported image using cfimage processing?

I am using ColdFusion 10.
When trying to read some image files, ColdFusion returns no values and no error messages are shown.
I tried to re-size an image using cfimage tag. It is crashing. So I tried to get info about the image using "imageinfo" function. It returns blank. Please help me to either get some info or skip the image. Can anyone help me?
I tried reading the file which caused the anomaly using
<cfimage action="read" source="full pathname" name="image">
<cfset image = imageRead(full pathname)>
and many other ColdFusion documented functions. No error was shown. No output was obtained. I used cffile which showed unsupported file type error.
<cffile
action = "readBinary" file = "full pathname" variable = "variable name"
>
Thanks Rino
Try using this function for reading images.
<cfimage> tag or imageNew() can have issues while trying to read image files which are corrupted or files saved with changed extensions (background transparent .png files saved as .jpeg) while uploading.
I think the main problem with these files is that there is a chance coldfusion doesn't throw an error of any sort when we try to read files mentioned above.
<cfscript>
public function readImage(fullpath){
//trying java imageio
var imageFile = createObject("java", "java.io.File").init(fullpath);
// read the image into a BufferedImage
var ImageIO = createObject("java", "javax.imageio.ImageIO");
try {
var bi = ImageIO.read(imageFile);
return ImageNew(bi);
} catch(any e) {
//try for bad formatted images
//create java file object, passing in path to image
var imageFile = createObject("java","java.io.File").init(fullpath);
//create a FileSeekableStream, passing in the image file we created
var fss = createObject("java","com.sun.media.jai.codec.FileSeekableStream").init(imageFile);
//create ParameterBlock object and initialize it (call constructor)
var pb = createObject("java","java.awt.image.renderable.ParameterBlock").init();
//create JAI object that will ultimately do the magic we need
var JAI = createObject("java","javax.media.jai.JAI");
try {
//pass in FileSeekableStream
pb.add(fss);
//use the JAI object to create a buffered jpeg image.
var buffImage = local.JAI.create("jpeg", pb).getAsBufferedImage();
//pass the buffered image to the ColdFusion imagenew()
var New_Image = imagenew(buffImage);
//make sure we close the stream
fss.close();
return New_Image;
} catch (any e) {
if (isDefined("fss")) {
fss.close();
}
rethrow;
}
}
}
</cfscript>

percent escapes removed in NSData writeToURL

I am trying to cache an image retrieved from Flickr. In order to create a unique filename for the cached image, I use CFURLCreateStringByAddingPercentEscapes to percent escape the URL. Appending that to the cache directory, I get a URL with the embedded Flickr URL properly percent escaped; but when I try to cache the image using NSData writeToURL:options:error: I get "The operation couldn’t be completed. No such file or directory" - and it shows the file URL with the original, unescaped Flickr URL where the file name should be.
For example, I NSLog the URL as:
file://localhost/Users/rick/Library/Application%20Support/iPhone%20Simulator/6.1/Applications/77C4A7AA-C386-4575-AD21-B4027D080408/Library/Caches/http%3A%2F%2Ffarm3.static.flickr.com%2F2887%2F9391679341_26643bcafa_b.jpg
but the error message shows
NSFilePath=/Users/rick/Library/Application Support/iPhone Simulator/6.1/Applications/77C4A7AA-C386-4575-AD21-B4027D080408/Library/Caches/http://farm3.static.flickr.com/2887/9391679341_26643bcafa_b.jpg
It's as if in the process of converting the URL to a file path, writeToURL is removing the percent escapes.
Is there a way to prevent this from happening, or do I just need to come up with another way to generate unique names based on the url?
Here's the relevant code:
NSURL *cacheDirectoryURL=[[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSString *photoURLString= (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)([self.photoURL absoluteString]),
NULL,
(CFStringRef) #"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8));
if (photoURLString)
{
NSURL *cachedPhotoURL=[NSURL URLWithString:[[cacheDirectoryURL absoluteString] stringByAppendingString:photoURLString]];
NSData *photoData=[NSData dataWithContentsOfURL:cachedPhotoURL];
if (photoData)
{
UIImage *image=[UIImage imageWithData:photoData];
self.imageView.image=image;
[self setupScrollView]; // new image, need to adjust scroll view
} else {
dispatch_queue_t fetchQueue=dispatch_queue_create("photo downloader", NULL);
dispatch_async(fetchQueue, ^{
NSData *photoData=[NSData dataWithContentsOfURL:self.photoURL];
NSError *error;
if ([photoData writeToURL:cachedPhotoURL options:NSDataWritingAtomic error:&error])
{
NSLog(#"Cached photo");
} else {
NSLog(#"Failed to cache photo");
NSLog(#"%#",error);
}
});
}
}
Thanks in advance for your help!
The problem is that [NSURL URLWithString:...] parses the given string and interprets the
percent escapes. Generally, to create a URL for a file system path, fileURLWithPath:
should be used.
In your case, the following simple code should work:
NSURL *cachedPhotoURL = [cacheDirectoryURL URLByAppendingPathComponent:photoURLString]

NSSearchPathForDirectoriesInDomains c++ equivalent

on objectiv-c I have the follow method:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
it return the app folders, on emulator:
/Users/ademar/Library/Application Support/iPhone Simulator/6.0/Applications/78A001F6-DDDE-4F6D-B762-8AAF42F1A1E3/Documents
I need the same on C++ but I'm not finding, have a similar method on c++?

How to Store the game score in android cocos2d

I calculates the score in game project using android cocos2d, in that game after finishing the first level it goes to the next level, so i want to store that first level score and also add next level scores. how can i store that scores in android-cocos2d.
Use NSKeyedArchiver class to store, here you have an example:
------------- WRITE
// get allowed save paths
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// string for the default path
NSString *documentsDirectory = [paths objectAtIndex:0];
// full path plus filename for save game
NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:#"gameState.dat"];
// storage for game state data
NSMutableData *gameData = [NSMutableData data];
// keyed archiver
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:gameData];
// encode all variables we want to track
[encoder encodeObject:[player inventoryDict] forKey:#"playerInventoryDict"];
[encoder encodeObject:[player equippedDict] forKey:#"playerEquippedDict"];
[encoder encodeInt:[player initialActionPoints] forKey:#"playerInitialActionPoints"];
[encoder encodeInt:[player actionPoints] forKey:#"playerActionPoints"];
[encoder encodeInt:[player experiencePoints] forKey:#"playerExperiencePoints"];
[encoder encodeInt:[player xpNextLevel] forKey:#"playerXPNextLevel"];
[encoder encodeBool:[player isThinking] forKey:#"playerIsThinking"];
// finish, write and release the encoder
[encoder finishEncoding];
[gameData writeToFile:gameStatePath atomically:YES];
[encoder release];
----------------- READ
// get allowed save paths
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// string for the default path
NSString *documentsDirectory = [paths objectAtIndex:0];
// full path plus filename for save game
NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:#"gameState.dat"];
// storage for game state data
NSMutableData *gameData = [NSMutableData data];
// start the decoder
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData];
// start with player data
PlayerEntity *player = [PlayerEntity player];
// variables from the PlayerEntity Class
player.inventoryDict = (NSDictionary *)[decoder decodeObjectForKey:#"playerInventoryDict"];
player.equippedDict = (NSDictionary *)[decoder decodeObjectForKey:#"playerEquippedDict"];
player.initialActionPoints = [decoder decodeIntForKey:#"playerInitialActionPoints"];
player.actionPoints = [decoder decodeIntForKey:#"playerActionPoints"];
player.experiencePoints = [decoder decodeIntForKey:#"playerExperiencePoints"];
player.xpNextLevel = [decoder decodeIntForKey:#"playerXPNextLevel"];
player.isThinking = [decoder decodeBoolForKey:#"playerIsThinking"];
// release the decoder
[decoder release];
Original code from HERE
sounds like what you're actually asking for here is how to store data for an app, which is technically nothing to do with cocos2d, as that's just a 2d rendering/graphics engine.
you could either create a customer content provider for your app which will give you a database to store your data in, however this approach is generally best suited for when you want other apps to be able to access your applications data. You could also use, for a more quick and dirty approach, a SharedPreferences approach.
android persistence is described well here
for a simply handle the score : you can use the static variable like "static int myscore ;" and apply some logic on it otherwise use the sqlite for handling the score event ....!!!!
I am guessing if you are using cocos2d for android port in java, this answer above in objective C might not be immediately useful to you. Here are some thought.
First, the simple approach is to create a database which you can read and write score data to . This will be the same as any android app.
There is a cocos2d android application thats been open sourced and which implements this ..
http://denvycom.com/blog/step-by-step-guide-on-how-to-build-your-first-slider-puzzle-game-in-cocos2d-for-android-part-1/
A specific example can be found here ...
https://github.com/chuvidi2003/GidiGames/blob/master/src/com/denvycom/gidigames/PuzzleLayer.java
mDbHelper = new DbAdapter(appcontext);
mDbHelper.open();
String labelmoves;
Cursor ScoreCursor = mDbHelper.fetchPuzzleBest("puzzlemania", GidiGamesActivity.currentpuzzletype,String.valueOf(NUM_ROWS)); // mDbHelper.fetchBestScore("puzzlemania", "");
if(ScoreCursor.getCount() > 0){
ScoreCursor.moveToFirst();
labelmoves = ScoreCursor.getString(ScoreCursor.getColumnIndex(
DbAdapter.KEY_GAME_MOVES)) ;
}
The above simple extracts some "moves" data from a database.
A similar approach can be used to also save data to a database .
See link below to learn more about database interaction in android
http://developer.android.com/training/basics/data-storage/databases.html
Best.

Converting GIF images to nsdata

I have an iPhone application that needs to save an image onto the database in BLOB format. The problem is that if the image is in .gif format then it cannot be converted to NSDATA format and hence i am not been able to save that onto the database in BLOB format.
What should I do?
Please help with some code..
Thanks in advance
Joy
A gif image can be converted into NSData...Here's the code snippet:
NSString *pathForGif = [[NSBundle mainBundle] pathForResource: #"gifFile" ofType: #"gif"];
NSData *gifData = [NSData dataWithContentsOfFile: pathForGif];
NSLog(#"Data: %#", gifData);
The log looked something like this:
Data: <47494638 39616400 6400f7ff 001f3546 a71a2568 7a85bacd caa8a99a a8ada689 969599a8
a7684430 282e3496 9b97b5bd b69aa69b 47596667 7679dbe9 eb076997 efd9ce0f 2532c9d6 cc908875
d7dddb86 8c89c9c7 bac8cdc9 c9764fc9 bcadd38f 69c8141e 6b554eb0 8e72a99a 8c566a74 e8ecedef
e8d48b77 6c733526 56636871 6555eed6 b8cdb294 ... 76797acc d9d76667 66ba6743 f2a30f88 948b5657
58999688 a95737fa d05edad9 cbd08658 aebbca37 55660516 248d6c55 acb7b847 5356dae8 dca95944
d8dceb4a 322c4646 45344956 353f4677 847aaa64 449a5436 020d13d7 ccb96c2c 17b7ab9a 8c9ba196>