iOS OpenCV 3.0 SVM save/load issue - opencv3.0

I can't save a trained SVM to a xml-file. This is my error:
OpenCV Error: Parsing error (Missing of invalid SVM type) in read_params, file /Users/build/test/opencv/modules/ml/src/svm.cpp, line 2050
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Users/build/test/opencv/modules/ml/src/svm.cpp:2050: error: (-212) Missing of invalid SVM type in function read_params
What do I do...
- (void)saveSVM {
string oFileName = "NormParameters.xml";
svm->save(oFileName);
}
- (BOOL)loadSVM {
string oFileName = "NormParameters.xml";
svm = StatModel::load<SVM>(oFileName);
NSLog(#"COUNT: %d", svm->getVarCount());
if (svm->getVarCount() > 0) {
return YES;
}
return NO;
}
SVM will be saved every time, if I get a new sample for it. The Loading of trained SVM happen in an initWithParams().
- (id)initWithParams {
self = [super init];
if (self) {
// create and set SVM parameters
SVM::Params param = SVM::Params();
param.svmType = SVM::EPS_SVR; // Support Vector Regression. The distance between feature vectors from the training set and the fitting hyper-plane must be less than p. For outliers the penalty multiplier C is used.
param.kernelType = SVM::RBF; //Polynomial kernel
param.degree = 3.0; // for poly
param.gamma = 1.0; // for poly/rbf/sigmoid
param.coef0 = 0.0; // for poly/sigmoid
param.C = 256.0; // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR
param.nu = 0.1; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR
param.p = 0.00390625; // for CV_SVM_EPS_SVR
param.classWeights = NULL; // for CV_SVM_C_SVC
param.termCrit.type = CV_TERMCRIT_EPS | CV_TERMCRIT_ITER; // CV_TERMCRIT_EPS + CV_TERMCRIT_ITER
param.termCrit.maxCount = 1000;
param.termCrit.epsilon = 0.00390625; //1e-6;
// create SVM
svm = SVM::create(param);
// load svm
[self loadSVM];
// create trained data
trainedDataMat = [[MLDataMatrix alloc] init];
[trainedDataMat removeDataRow];
}
return self;
}
I am new in OpenCV may be I set wrong parameters (I played with all of them) or StatModel::load don't work unter iOS 8.3?
If you know another way to save SVM to a file, please let me know too...
Thank you for each answer!

Related

Is there any way to find the scaling coefficient for a CGDisplay?

I'm currently doing some tests to see if my app runs correctly on Retina Macs. I have installed Quartz Debug for this purpose and I'm currently running a scaled mode. My screen mode is now 960x540 but of course the physical size of the monitor is still Full HD, i.e. 1920x1080 pixels.
When querying the monitor database using CGGetActiveDisplayList() and then using CGDisplayBounds() on the individual monitors in the list, the returned monitor size is 960x540. This is what I expected because CGDisplayBounds() is said to use the global display coordinate space, not pixels.
To my surprise, however, CGDisplayPixelsWide() and CGDisplayPixelsHigh() also return 960x540, although they're explicitly said to return pixels so I'd expect them to return 1920x1080 instead. But they don't.
This leaves me wondering how can I retrieve the real physical resolution of the monitor instead of the scaled mode using the CGDisplay APIs, i.e. 1920x1080 instead of 960x540 in my case? Is there any way to get the scaling coefficient for a CGDisplay so that I can compute the real physical resolution on my own?
I know I can get this scaling coefficient using the backingScaleFactor method but this is only possible for NSScreen, how can I get the scaling coefficient for a CGDisplay?
You need to examine the mode of the display, not just the display itself. Use CGDisplayCopyDisplayMode() and then CGDisplayModeGetPixelWidth() and CGDisplayModeGetPixelHeight(). These last two are relatively newer functions and the documentation primarily exists in the headers.
And, of course, don't forget to CGDisplayModeRelease() the mode object.
From Ken's answer it is not obvious how you find the native mode(s). To do this, call CGDisplayModeGetIOFlags and choose from the modes that have the kDisplayModeNativeFlag set (see IOKit/IOGraphicsTypes.h, the value is 0x02000000).
const int kFlagNativeMode = 0x2000000; // see IOGraphicsTypes.h
const CGFloat kNoSize = 100000.0;
NSScreen *screen = NSScreen.mainScreen;
NSDictionary *desc = screen.deviceDescription;
unsigned int displayID = [[desc objectForKey:#"NSScreenNumber"] unsignedIntValue];
CGSize displaySizeMM = CGDisplayScreenSize(displayID);
CGSize nativeSize = CGSizeMake(kNoSize, kNoSize);
CFStringRef keys[1] = { kCGDisplayShowDuplicateLowResolutionModes };
CFBooleanRef values[1] = { kCFBooleanTrue };
CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
CFArrayRef modes = CGDisplayCopyAllDisplayModes(displayID, options);
int n = CFArrayGetCount(modes);
for (int i = 0; i < n; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (CGDisplayModeGetIOFlags(mode) & kFlagNativeMode) {
int w = CGDisplayModeGetWidth(mode);
// We get both high resolution (screen.backingScaleFactor > 1)
// and the "low" resolution, in CGFloat units. Since screen.frame
// is CGFloat units, we want the lowest native resolution.
if (w < nativeSize.width) {
nativeSize.width = w;
nativeSize.height = CGDisplayModeGetHeight(mode);
}
}
// printf("mode: %dx%d %f dpi 0x%x\n", (int)CGDisplayModeGetWidth(mode), (int)CGDisplayModeGetHeight(mode), CGDisplayModeGetWidth(mode) / displaySizeMM.width * 25.4, CGDisplayModeGetIOFlags(mode));
}
if (nativeSize.width == kNoSize) {
nativeSize = screen.frame.size;
}
CFRelease(modes);
CFRelease(options);
float scaleFactor = screen.frame.size.width / nativeSize.width;

Displaying float to a variable number of decimal places in Swift

Is there a simple way of displaying a float or double to a relevant number of decimal places in Swift.
For example, an iOS app using SI units, which can be altered depending on the property desired, and converted through up to 6 orders of magnitude depending on desired inputs and output. Therefore it needs to display not only 1mg to 1000 micrograms, but also the other way around - i.e 1 microgram = 0.001 mg.
I can easily format a string as follows:
textFieldFoo.text = NSString(format: "%.1f mg", bar) as String
However, if the user were to convert from 1mcg to 0.001mg, this would display as
0.0 mg
Yet, to include up to 6 decimal places to encompass all common possibilities would lead to an unwieldy, ugly looking UI.
Is there a simple way to format a string, in order to include a float/ double where it is displayed to a relevant number of decimal places/ significant figures? I'm sure, given time and enough boilerplate code, that I could pyramid if/ else it to get a result, but that's frankly inelegant.
There's NSMAssFormatter but it doesn't go all the way down to microgram. It was designed to format human-level weight.
You can roll your own by subclassing NSNumberFormatter:
enum MassUnit: Double {
case Microgram = 1e-6
case Milligram = 1e-3
case Gram = 1
case Kilogram = 1e3
static let allUnits: [MassUnit] = [.Microgram, .Milligram, .Gram, .Kilogram]
var unitAbbreviation: String {
get {
switch self {
case .Microgram: return "mcg"
case .Milligram: return "mg"
case .Gram: return "g"
case .Kilogram: return "kg"
}
}
}
}
class MyMassFormatter: NSNumberFormatter {
func bestFitStringForWeightInGrams(weight: Double) -> String {
var selectedString = self.stringFromNumber(weight)!
var selectedUnit = MassUnit.Gram
// Pick the unit that results in the shortest string
for unit in MassUnit.allUnits {
if let str = self.stringFromNumber(weight / unit.rawValue)
where str.characters.count < selectedString.characters.count {
selectedString = str
selectedUnit = unit
}
}
return selectedString + selectedUnit.unitAbbreviation
}
}
Usage:
let formatter = MyMassFormatter()
formatter.format = "0.######"
print(formatter.bestFitStringForWeightInGrams(0.000001)) // 1mcg
print(formatter.bestFitStringForWeightInGrams(0.005)) // 5mg
print(formatter.bestFitStringForWeightInGrams(2500)) // 2.5kg
print(formatter.bestFitStringForWeightInGrams(1234.5)) // 1234.5g
Formatting to Significant Figures using Swift
What you want is the ability to format to a fixed number of significant figures, rather than a fixed number of decimal places. A good swift option to solve this is using class extensions, with a little maths to decide how many decimal places to show based on the magnitude of the number.
The example below extends the Double class to enable formatting to a fixed number of significant figures and uses either float notation or scientific notation depending on the magnitude of the number.
import Foundation
//extension to format a Double to a fixed number of significant figures
extension Double {
func sigFigs(_ numberOfSignificantFigures: Int) -> String {
let mag = log10(abs(self))
let intMag = Int(mag)
if mag >= 0 {
if intMag < numberOfSignificantFigures {
return String(format: "%.\(numberOfSignificantFigures - intMag - 1)f",self)
}
else {
return String(format: "%.\(numberOfSignificantFigures - 1)e",self)
}
}
else {
if -intMag < numberOfSignificantFigures {
return String(format: "%.\(numberOfSignificantFigures)f",self)
}
else {
return String(format: "%.\(numberOfSignificantFigures - 1)e",self)
}
}
}
}
Usage
let num1 = 1234.5678
let num2 = 12.345678
let num3 = 0.0012345678
let num4 = 1234567.8
print(num1.sigFigs(6))
print(num1.sigFigs(2))
print(num2.sigFigs(6))
print(num2.sigFigs(2))
print(num3.sigFigs(6))
print(num3.sigFigs(2))
print(num4.sigFigs(6))
print(num4.sigFigs(2))
Output
1234.57
1.2e+03
12.3457
12
0.001235
1.2e-03
1.23457e+06
1.2e+06
If I understand you correctly you are:
using Swift
working with SI units
trying to display floating points
trying to avoid boilerplate and possibly magic numbers
You should definitely use Apple's Measurement which is :
A numeric quantity labeled with a unit of measure, with support for unit conversion and unit-aware calculations.
and MeasurementFormatter which is :
A formatter that provides localized representations of units and measurements.
MeasurementFormatter uses a NumberFormatter to format the quantity of a measurement.
NumberFormatters's usesSignificantDigits property is set to false by default but :
Set this property to true to format numbers according to the significant digits configuration specified by the minimumSignificantDigits and maximumSignificantDigits properties. By default, the minimum number of significant digits is 1, and the maximum number of significant digits is 6.
Here's an example of what you can do with masses
let micrograms = Measurement(value: 1, unit: UnitMass.micrograms) // 1.0 µg
let nanograms = micrograms.converted(to: .nanograms) // 1000.0000000000001 ng
let picograms = micrograms.converted(to: .picograms) // 1000000.0 pg
let milligrams = micrograms.converted(to: .milligrams) // 0.001 mg
let centigrams = micrograms.converted(to: .centigrams) // 0.0001 cg
let decigrams = micrograms.converted(to: .decigrams) // 1e-05 dg
let grams = micrograms.converted(to: .grams) // 1e-06 g
let kilograms = micrograms.converted(to: .kilograms) // 1e-09 kg
let ounces = micrograms.converted(to: .ounces) // 3.527399072294044e-08 oz
let pounds = micrograms.converted(to: .pounds) // 2.2046244201837776e-09 lb
let stones = micrograms.converted(to: .stones) // 1.574731232746851e-10 st
let formatter = MeasurementFormatter()
formatter.numberFormatter.usesSignificantDigits = true
formatter.unitOptions = .providedUnit
formatter.string(from: nanograms) // "1 000 ng"
formatter.string(from: picograms) // "1 000 000 pg"
formatter.string(from: micrograms) // "1 µg"
formatter.string(from: milligrams) // "0,001 mg"
formatter.string(from: centigrams) // "0,0001 cg"
formatter.string(from: decigrams) // "0,00001 dg"
formatter.string(from: grams) // "0,000001 g"
formatter.string(from: kilograms) // "0,000000001 kg"
formatter.string(from: ounces) // "0,000000035274 oz"
formatter.string(from: pounds) // "0,00000000220462 lb"
formatter.string(from: stones) // "0,000000000157473 st"

SpriteKit Animation Physics

is there a way to apply skphysics to a animated character? Okay I have my player play an animation when I move it around the screen and below is it's animation code but for some reason when I want to apply physics to my animation, I get an error saying wrong data type.
Sending 'SKSpriteNode *_strong' to parameter of incompatible type 'CGRect' (aka 'struct CGRect')
NO Reputation and I can't answer my own question so I posted here.
actually never mind I had to add this _Player.frame and I am hoping this is right and is putting physics on my character. However, please correct me if I am wrong. thanks.
- (void) Player {
_Player = [SKSpriteNode spriteNodeWithImageNamed:#"bird"];
_Player.xScale = 0.88;
_Player.yScale = 0.88;
_Player.position = CGPointMake(100, 100);
[self addChild:_Player];
// 1
NSMutableArray *PlayerCh = [NSMutableArray arrayWithCapacity:2];
// 2
for (int i = 1; i < 2; i++) {
NSString *mytextureName = [NSString stringWithFormat:#"bird%d", i];
SKTexture *ItsTexture = [SKTexture textureWithImageNamed:mytextureName];
[PlayerCh addObject:ItsTexture];
}
// 3
for (int i = 2; i > 1; i--) {
NSString *mytextureName = [NSString stringWithFormat:#"bird%d", i];
SKTexture *ItsTexture = [SKTexture textureWithImageNamed:mytextureName];
[PlayerCh addObject:ItsTexture];
}
// 4
_PlayerAnimation = [SKAction animateWithTextures:PlayerCh timePerFrame:0.1];
// SKPHYSICS FOR PLAYER
SKPhysicsBody *MYPLAYER = [SKPhysicsBody bodyWithCircleOfRadius:_Player]; // I get a error here.
}
Of course this program has to crash when it runs
[SKPhysicsBody bodyWithCircleOfRadius:_Player] expects a float not an SKPriteNode, what you probably want to do is change this line of code to the following:
SKPhysicsBody *MYPLAYER = [SKPhysicsBody bodyWithCircleOfRadius:_Player.size.width/2];

How can I get an NSImage from a CMSampleBuffer obtained from -captureStillImageAsynchronouslyFromConnection:completionHandler:?

I have a Cocoa app that is intended to capture still images from a USB microscope and then do some post-processing on them before saving them to an image file. At the moment, I am stuck trying to get from the CMSampleBufferRef that's passed to my completionHandler block to an NSImage or some other representation I can manipulate and save using familiar Cocoa APIs.
I found the function imageFromSampleBuffer() in the AVFoundation docs, which purports to convert a CMSampleBuffer to a UIImage (sigh), and revised it appropriately to return an NSImage. But it does not work in this case, as the call to CMSampleBufferGetImageBuffer() returns nil.
Here is a log showing the CMSampleBuffer passed to my completion block:
2012-01-21 19:38:36.293 LabCam[1402:cb0f] CMSampleBuffer 0x100335390 retainCount: 1 allocator: 0x7fff8c78620c
invalid = NO
dataReady = YES
makeDataReadyCallback = 0x0
makeDataReadyRefcon = 0x0
buffer-level attachments:
com.apple.cmio.buffer_attachment.discontinuity_flags(P) = 0
com.apple.cmio.buffer_attachment.hosttime(P) = 79631546824089
com.apple.cmio.buffer_attachment.sequence_number(P) = 42
formatDescription = <CMVideoFormatDescription 0x100335220 [0x7fff782fff40]> {
mediaType:'vide'
mediaSubType:'jpeg'
mediaSpecific: {
codecType: 'jpeg' dimensions: 640 x 480
}
extensions: {<CFBasicHash 0x100335160 [0x7fff782fff40]>{type = immutable dict, count = 5,
entries =>
1 : <CFString 0x7fff773dff48 [0x7fff782fff40]>{contents = "Version"} = <CFNumber 0x183 [0x7fff782fff40]>{value = +1, type = kCFNumberSInt32Type}
2 : <CFString 0x7fff773dff68 [0x7fff782fff40]>{contents = "RevisionLevel"} = <CFNumber 0x183 [0x7fff782fff40]>{value = +1, type = kCFNumberSInt32Type}
3 : <CFString 0x7fff7781ab08 [0x7fff782fff40]>{contents = "CVFieldCount"} = <CFNumber 0x183 [0x7fff782fff40]>{value = +1, type = kCFNumberSInt32Type}
4 : <CFString 0x7fff773dfdc8 [0x7fff782fff40]>{contents = "FormatName"} = <CFString 0x7fff76d35fb0 [0x7fff782fff40]>{contents = Photo - JPEG"}
5 : <CFString 0x7fff773dff88 [0x7fff782fff40]>{contents = "Vendor"} = <CFString 0x7fff773dffa8 [0x7fff782fff40]>{contents = "appl"}
}
}
}
sbufToTrackReadiness = 0x0
numSamples = 1
sampleTimingArray[1] = {
{PTS = {2388943236/30000 = 79631.441, rounded}, DTS = {INVALID}, duration = {3698/30000 = 0.123}},
}
sampleSizeArray[1] = {
sampleSize = 55911,
}
dataBuffer = 0x100335300
It clearly appears to contain JPEG data, but how do I get at it? (Preferably keeping the associated metadata along for the ride…)
I eventually solved this with help from another code example. CMSampleBufferGetImageBuffer only returns a valid result for the uncompressed, native image formats available from the camera. So to get my program to work, I had to configure the AVCaptureStillImageOutput instance to use k32BGRAPixelFormat instead of its default (JPEG) compressed format.
session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetPhoto;
imageOutput = [[AVCaptureStillImageOutput alloc] init];
// Configure imageOutput for BGRA pixel format [#2].
NSNumber * pixelFormat = [NSNumber numberWithInt:k32BGRAPixelFormat];
[imageOutput setOutputSettings:[NSDictionary dictionaryWithObject:pixelFormat
forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
[session addOutput:imageOutput];

how to set "smart" breakpoint in Xcode when method returns a specific value?

I have a method which returns a bool value, with several exit points.
However, it does not seem to work correctly, so I would like to set an automatic breakpoint to see when it returns a YES value, so I can check all the variables and calculations in the debugger.
I would like to stop the debugger whenever a YES value is returned.
I have a similar smart breakpoint set for objc_exception_throw, so I know it's possible, I am just not sure how.
(In case it helps anyone, the way you can set the exception breakpoint: in the Breakpoints window (Run -> Show -> Breakpoints) enter objc_exception_throw as "Breakpoint", and libobjc.A.dylib as "Location")
EDIT: the specific code I would like to use it for:
- (BOOL)collisionOccured {
// Assumption: helicopter is of square shape (collision calculated by radius), walls are rectangles
// This approach is based on the solution seen here: http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection/402010#402010
float helicopterImageWidth = [helicopter texture].contentSize.width;
float wallImageWidth = [[walls lastObject] texture].contentSize.width;
float wallImageHeight = [[walls lastObject] texture].contentSize.height;
float helicopterCollisionRadius = helicopterImageWidth * 0.4f;
CGPoint helicopterPosition = helicopter.position;
int numWalls = [walls count];
for (int i = 0; i < numWalls; i++) {
CCSprite *wall = [walls objectAtIndex:i];
if ([wall numberOfRunningActions] == 0) {
// The wall is not moving, we can skip checking it.
continue;
}
CGPoint wallPosition = wall.position;
float helicopterDistanceX = abs(helicopterPosition.x - wallPosition.x - wallImageWidth/2);
float helicopterDistanceY = abs(helicopterPosition.y - wallPosition.y - wallImageHeight/2);
if (helicopterDistanceX > (wallImageWidth/2 + helicopterCollisionRadius)) { return NO; }
if (helicopterDistanceY > (wallImageHeight/2 + helicopterCollisionRadius)) { return NO; }
if (helicopterDistanceX <= (wallImageWidth/2)) { return YES; }
if (helicopterDistanceY <= (wallImageHeight/2)) { return YES; }
float cornerDistance_sq = powf((helicopterDistanceX - wallImageWidth/2), 2) +
powf((helicopterDistanceY - wallImageHeight/2), 2);
return (cornerDistance_sq <= powf(helicopterCollisionRadius, 2));
}
// this should not occur
return NO;
}
This method is called via
- (void)update:(ccTime)delta {
if ([self collisionOccured]) {
NSLog(#"A collision occured");
}
}
The problem is that the update method takes delta (time passed) as argument, so I can't check what's happening frame by frame -- whenever I continue the execution, I am presented with a different scene.
(I am using cocos2d in the code)
You can set conditional breakpoints. With a slight tweak to update:
- (void)update:(ccTime)delta {
BOOL collided = [self collisionOccured];
if (collided) {
NSLog(#"A collision occured");
}
}
you can set a breakpoint as normal after the BOOL's assignment (i.e. on the if line), then right-click on the blue breakpoint arrow and select "Show Message Bubble", and add collided as the Condition. The extra variable should get optimized away in Release build mode.
If you're using a local return variable:
- (BOOL)someMethod {
BOOL ret = NO;
if (something) {
ret = YES;
} else if (something_else) {
ret = YES;
}
// ... and so on
return ret;
}
You can just set a watch point on ret
Otherwise, you're probably stuck with stepping through the code—hopefully some clever combination of conditional breakpoints will help you not have to break on every invocation. Setting a method breakpoint like you do with objc_exception_throw wouldn't work, because it will stop on every invocation, and breaking on the return value at the calling site is too late to figure out how you got there.
If you can post the code, we may be able to give more specific help as to a debugging strategy. Good luck. :-)

Resources