#interface FJFaceRecognizer () {
Ptr<FaceRecognizer> _faceClassifier;
}
#property (nonatomic, strong) NSMutableDictionary *labelsDictionary;
#end
#implementation FJFaceRecognizer
- (NSArray *)labels {
On next line I get error message No member named 'getMat' in 'cv::face::FaceRecognizer', when using OpenCV 3.0:
cv::Mat labels = _faceClassifier->getMat("labels");
if (labels.total() == 0) {
return #[];
}
else {
NSMutableArray *mutableArray = [NSMutableArray array];
for (MatConstIterator_<int> itr = labels.begin<int>(); itr != labels.end<int>(); ++itr ) {
int lbl = *itr;
[mutableArray addObject:#(lbl)];
}
return [NSArray arrayWithArray:mutableArray];
}
}
}
What should I use instead of getMat in OpenCV 3.0?
If you want std::vector<int> of labels, you should be able to use getLabelsByString
http://docs.opencv.org/master/dd/d65/classcv_1_1face_1_1FaceRecognizer.html
Might be worth looking over the transition guide going from 2 to 3
http://docs.opencv.org/master/db/dfa/tutorial_transition_guide.html
Related
I trying to learn how to save array of objects using NSKeyedArchiver and I coded a small application to do that and I logged to see if the array was saved but everytime I get 0 for array count and here is the code.
ViewController.h
#interface ViewController : UIViewController
{
IBOutlet UITextField *text;
IBOutlet UITextField *textName;
IBOutlet UITextField *textAge;
IBOutlet UILabel *name;
IBOutlet UILabel *age;
BOOL flag;
BOOL choice;
NSString *documentDirectory;
NSMutableArray *anArray;
Person *p;
NSData *data;
}
-(BOOL) dataFilePath;
-(IBAction)readPlist;
-(IBAction) writePlist;
#property (strong,nonatomic)IBOutlet UITextField *text;
#property (strong,nonatomic)IBOutlet UITextField *textName;
#property (strong,nonatomic)IBOutlet UITextField *textAge;
#property (strong,nonatomic)IBOutlet UILabel *name;
#property (strong,nonatomic)IBOutlet UILabel *age;
#property (strong,nonatomic)NSString *documentDirectory;
#property (strong,nonatomic)NSMutableArray *anArray;
#end
ViewController.m
#interface ViewController ()
#end
#implementation ViewController
#synthesize text,documentDirectory,textAge,textName,name,age,anArray;
- (void)viewDidLoad
{
[super viewDidLoad];
// checking if the file was created and show a message if its created or not.
if ([self dataFilePath]) {
NSLog(#"File Created !");
} else {
NSLog(#"File Not Created !");
}
NSLog(#"File location : %#",documentDirectory);
choice = YES;
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL) dataFilePath
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentDirectory = [path objectAtIndex:0];
documentDirectory = [documentDirectory stringByAppendingPathComponent:#"MilmersĀData.dat"];
return TRUE;
}
- (IBAction)writePlist
{
p.name = textName.text;
p.age = [textAge.text intValue];
[anArray addObject:p];
for (int i=0; i<[anArray count]+1; i++) {
Person *pp = [[Person alloc]init];
pp=[anArray objectAtIndex:i];
NSLog(#"Name: %#",pp.name); // checking the names in pp object but getting null
}
data = [NSKeyedArchiver archivedDataWithRootObject:anArray];
[data writeToFile:documentDirectory options:NSDataWritingAtomic error:nil];
NSLog(#"Array length: %d",[anArray count]); //Always got array count zero.
}
-(IBAction)readPlist
{
NSString *filePath = documentDirectory;
NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(#"The array is: %#",array); // it shows that there is nothing in the array
}
#end
I wrote the class for writing .plist files originally but I knew later that I cant store objects in .plist file so I tried so that with archive, thats why the method name have plist in it.
Thank you in advance
Looks like you aren't ever creating an instance of p to add to the array. Try:
Person *p = [[Person alloc] init];
p.name = textName.text;
p.age = [textAge.text intValue];
[anArray addObject:p];
your index limit was also wrong in this loop
for (int i=0; i<[anArray count]; i++) {
NSLog(#"Name: %#", [[anArray objectAtIndex:i] name]);
}
you should really have been seeing a couple of different crashes...
Try adding this in viewDidLoad
[[NSFileManager defaultManager] createFileAtPath:documentDirectory contents:nil error:nil];
It looks like you never do this, and using archives to write to files only works if the file already exists (make sure you only do this once, otherwise every time that view is loaded the file will be emptied of all the data in it). And when you do this
if ([self dataFilePath])
It's pointless, because no matter what it always returns yes, whether the file exists or not.
Does your Person class implement NSCoding?
Specifically you need to implement something like the following in Person.m:
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.name = [decoder decodeObjectForKey:#"name"];
self.age = [decoder decodeObjectForKey:#"age"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeObject:self.age forKey:#"age"];
}
First off, I come from Lua, don't blame me for being global variable minded lol. So, I've been reading up on how to use this whole "Singleton system" and I'm not sure if I'm completely missing the point or if I'm just implementing it incorrectly?
The goal of my code is to create a way for multiple files to access a variable that holds the size of an array in a specific file. Here is my singleton:
.h
#import <Foundation/Foundation.h>
#interface GlobalVariables : NSObject
{
NSNumber *currentGameArrayCount;
BOOL *isGamePaused;
}
#property (nonatomic, readwrite) NSNumber *currentGameArrayCount;
#property (nonatomic, readwrite) BOOL *isGamePaused;
+ (GlobalVariables *)sharedInstance;
#end
.m
#import "GlobalVariables.h"
#implementation GlobalVariables
#synthesize currentGameArrayCount, isGamePaused;
static GlobalVariables *gVariable;
+ (GlobalVariables *)sharedInstance
{
if (gVariable == nil) {
gVariable = [[super allocWithZone:NULL] init];
}
return gVariable;
}
- (id)init
{
self = [super init];
if (self)
{
currentGameArrayCount = [[NSNumber alloc] initWithInt:0];
isGamePaused = NO;
}
return self;
}
#end
and in another file with the array I use:
GlobalVariables *sharedData = [GlobalVariables sharedInstance];
NSNumber *tmpArrayCount = [sharedData currentGameArrayCount];
NSInteger tmpCount = [whereStuffActuallyHappens.subviews count]; // Subviews is the array
NSNumber *currentCount = [NSNumber numberWithInteger:tmpCount];
tmpArrayCount = currentCount;
the hope of this code was to get the variable in the singeton (currentGameArrayCount) and set it too what the current array count was (currentCount). Am I incorrectly interpreting the purpose of a singleton? Am I just bad at singletons and didn't set it up correctly? Does anyone know how I could achieve the result of getting my array count to be accesible to all my files?
You have a few issues. Try these changes:
GlobalVariables.h:
#import <Foundation/Foundation.h>
#interface GlobalVariables : NSObject
#property (nonatomic, assign) int currentGameArrayCount;
#property (nonatomic, assign) BOOL gamePaused;
+ (GlobalVariables *)sharedInstance;
#end
GlobalVariables.m:
#import "GlobalVariables.h"
static GlobalVariables *gVariable = nil;
#implementation GlobalVariables
+ (GlobalVariables *)sharedInstance {
if (gVariable == nil) {
gVariable = [[self alloc] init];
}
return gVariable;
}
- (id)init {
self = [super init];
if (self) {
self.currentGameArrayCount = 0;
self.gamePaused = NO;
}
return self;
}
#end
Now in your other code you can do:
GlobalVariables *sharedData = [GlobalVariables sharedInstance];
int tmpArrayCount = sharedData.currentGameArrayCount;
NSInteger tmpCount = [whereStuffActuallyHappens.subviews count]; // Subviews is the array
sharedData.currentGameArrayCount = tmpCount;
I have a json string:
{"1":{"homeTeam":"Home01","awayTeam":"Away01","homeScore":0,"awayScore":0,"gameID":1},"2":{"homeTeam":"Home11","awayTeam":"Away11","homeScore":0,"awayScore":0,"gameID":2},"3":{"homeTeam":"Home21","awayTeam":"Away21","homeScore":0,"awayScore":0,"gameID":3}}
that I would like to turn into an Objective-C class:
#import <Foundation/Foundation.h>
#interface ScoreKeeperGame : NSObject {
}
#property (nonatomic, retain) NSString *homeTeam;
#property (nonatomic, retain) NSString *awayTeam;
#property (nonatomic, assign) int homeScore;
#property (nonatomic, assign) int awayScore;
#property (nonatomic, assign) int gameID;
- (id) init: (NSString *) homeTeam
awayTeam: (NSString *) awayTeam;
- (id) init: (NSDictionary *) game;
#end
I pass the json in by NSDictionary "game" (the json string represents a hashmap, so the first game is):
{"homeTeam":"Home01","awayTeam":"Away01","homeScore":0,"awayScore":0,"gameID":1}
When I try to use this class:
#import "ScoreKeeperGame.h"
#implementation ScoreKeeperGame
#synthesize homeTeam=_homeTeam, awayTeam = _awayTeam, homeScore = _homeScore, awayScore = _awayScore, gameID = _gameID;
- (id) init: (NSString *) homeTeam
awayTeam: (NSString *) awayTeam
{
self = [super init];
self.homeTeam = homeTeam;
self.awayTeam = awayTeam;
NSLog(#"away: %#", awayTeam);
return self;
}
- (id) init: (NSDictionary *) game
{
self = [super init];
if(self)
{
self.homeTeam = [game objectForKey:#"homeTeam"];
self.awayTeam = [game objectForKey:#"awayTeam"];
self.awayScore = (int) [game objectForKey:#"awayScore"];
self.gameID = [game objectForKey:#"gameID"];
NSLog(#"game awayScore: %d", self.awayScore);
NSLog(#"game gameID: %#", [NSNumber numberWithInt:self.gameID]);
}
return self;
}
#end
The awayScore and gameId are printed as large numbers (maybe pointers)?
I've tried
self.awayScore = [NSNumber numberWithInt: [game objectForKey:#"awayScore"]];
But that didn't seem to work either.
How do I get the value of the int from the game object?
po game produces:
{
awayScore = 0;
awayTeam = Away01;
gameID = 1;
homeScore = 0;
homeTeam = Home01;
}
Thanks!
You have to pull it out as an NSNumber first.
NSNumber *myNum = [game objectForKey:#"awayScore"];
self.awayScore = [myNum intValue];
Doh!
you can try this if you want to get integer value from your JSON response
self.awayScore = [NSNumber numberWithInt: [[game objectForKey:#"awayScore"] intValue]];
as your response would be in nsstring.
iOs 6.0, now it's simply [game[#"awayScore"] intValue]
I've built a singleton object to manage some data in my app
#interface MyCommon : NSObject {
NSArray *quizz;
int iCurrentQuestion;
};
+ (MyCommon *)singleton;
#property (retain) NSArray *quizz;
#property (assign) int iCurrentQuestion;
#end
MyCommon.m
#import "MyCommon.h"
// MyCommon.m:
#implementation MyCommon
static MyCommon * MyCommon_Singleton = nil;
#synthesize iCurrentQuestion;
+ (MyCommon *)singleton
{
if (nil == MyCommon_Singleton)
{
MyCommon_Singleton = [[MyCommon alloc] init];
NSLog(#"allocating MyCommon_Singleton at %#",MyCommon_Singleton);
}
else {
NSLog(#"accessing singleton : %#", MyCommon_Singleton);
}
return MyCommon_Singleton;
}
- (NSArray*) getQuizz{
return quizz;
}
- (void) setQuizz:(NSArray *)array {
quizz = [NSArray arrayWithArray:array];
NSLog(#"setQuizz : %#",quizz);
}
There is no problem for writing the quizz object (setQuizz), however when I try to access it for reading, I get a crash : the quizz looks invalid and Xcode notify me an invalid CFArrayRef
I don't know what's wrong with my code.
You provide a custom setter for quizz but it doesn't comply with how the property is declared.
You're not retaining quizz when you're setting a new value. It's likely to be released just after, leading to a crash when you access it.
You should write
- (void)setQuizz:(NSArray *)array {
if (quizz != array) {
NSArray *tmp = quizz;
quizz = [array retain]; // retain the new value
[tmp release]; // release the old one
}
NSLog(#"setQuizz : %#",quizz);
}
this is way more code than it needs to be. First if you are going to be providing your own method you should declare so in the #property declaration which you didn't. Also your not properly retaining your variables. Additionally you should be using dispatch_once() for a thread safe & fast way to guarantee the singleton is only created once.
#interface MyCommon : NSObject {}
#property(nonatomic, retain) NSArray *quiz;
#property (assign) int iCurrentQuestion;
+ (MyCommon *)singleton;
#end
#implementation MyCommon
#synthesize quiz;
#synthesize iCurrentQuestion;
-(id)init {
self = [super init];
if(self) {
quiz = [[NSMutableArray alloc init];
iCurrentQuestion = 0;
}
return self;
}
+ (MyCommon *)singleton {
static MyCommon *singleton = nil;
static dispatch_once_t pred;
dispatch_once(&pred, ^{
singleton = [[MyCommon alloc] init];
});
return singleton;
}
#end
then you just do
[MyCommon singleton].quiz = //some array
For a little iPhone application I am making, I want to sort a NSMutableArray.
I found 2 ways of doing this, but they both result in the same thing. Sorting the array will cause some objects to 'overwrite' eachother.
First off, here is my code:
AppDelegate.h
NSMutableArray* highScores;
Somewhere down that AppDelegate.h, I also make this variable a property so that I can access it from differen classes:
#property (retain, nonatomic) NSMutableArray* highScores;
When my application starts, I read the high scores from a file and import them into my NSMutableArray.
AppDelegate.m
NSMutableData* data = [NSData dataWithContentsOfFile:highScoresPath];
NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
self.highScores = [decoder decodeObjectForKey:#"highscoresArray"];
The objects I store in this NSMutableArray are from the type HighScore.
HighScore.h
#interface HighScore : NSObject {
int score;
int roundsPlayed;
int wrongAnswers;
NSString* name;
NSDate* datetime;
}
#property int score;
#property int roundsPlayed;
#property int wrongAnswers;
#property (nonatomic, copy) NSDate* datetime;
#property (nonatomic, copy) NSString* name;
- (id) init;
- (void) update:(int)roundScore:(BOOL) correct;
#end
HighScore.m
#import "HighScore.h"
#implementation HighScore
#synthesize score, roundsPlayed, wrongAnswers, name, datetime;
- (id) init
{
self.name = #"";
self.score = 0;
self.roundsPlayed = 0;
self.wrongAnswers = 0;
self.datetime = [NSDate date];
return self;
}
- (void) update:(int)roundScore:(BOOL) correct
{
self.score += roundScore;
if (!correct)
self.wrongAnswers++;
self.roundsPlayed++;
self.datetime = [NSDate date];
}
- (id) initWithCoder:(NSCoder *) decoder
{
self.name = [[decoder decodeObjectForKey:#"name"] retain];
self.score = [decoder decodeIntForKey:#"score"];
self.roundsPlayed = [decoder decodeIntForKey:#"roundsPlayed"];
self.wrongAnswers = [decoder decodeIntForKey:#"wrongAnswers"];
self.datetime = [[decoder decodeObjectForKey:#"datetime"] retain];
return self;
}
- (void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeInt:self.score forKey:#"score"];
[encoder encodeInt:self.roundsPlayed forKey:#"roundsPlayed"];
[encoder encodeInt:self.wrongAnswers forKey:#"wrongAnswers"];
[encoder encodeObject:self.datetime forKey:#"datetime"];
}
- (NSComparisonResult) compareHighscore:(HighScore*) h
{
return [[NSNumber numberWithInt:self.score] compare:[NSNumber numberWithInt:h.score]];
}
#end
Now, when I try to sort my array by using the following code:
NSArray *sortedArray;
sortedArray = [highScores sortedArrayUsingSelector:#selector(compareHighscore:)];
It somehow screws up my highScores array, I get an X amound of highscores with the same score and name.
What am I doing wrong?
I'm noticing that in your initWithCoder: method, you're not doing this:
if (self = [super initWithCoder:coder]) {
// Decode your stuff here
}
Same with your regular init method. There needs to be a call to [super init].
Also, since you defined your string properties as copy and you're using the property syntax, there's no need to retain them. They will be retained for you by the synthesized accessor.
Otherwise, your code looks fine to me. Just remember: every init method must always have a call to a super's init... method.
You're trying to sort using #selector(compare:), not #selector(compareHighscore:), which I presume was your intention.
try
sortedArray = [highScores sortedArrayUsingSelector:#selector( compareHighscore: )];
Post the actual compareHighscore: method. The most important thing is that it has to be consistent, that is if a <= b and b <= c, then a <= c and if a < b and b < c then a < c. If you managed to write a compare method that is not consistent, anything can happen.