Platforms to show: All Mac Windows Linux Cross-Platform
Required plugins for this example: MBS Mac64bit Plugin, MBS Main Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Mac64bit/CoreML/CoreML Test
This example is the version from Fri, 2nd Nov 2017.
Project "CoreML Test.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Open()
#if Target64Bit and TargetMacOS then
// ok
if not MLModelMBS.available then
MsgBox "Please run on macOS High Sierra or newer."
quit
end if
#else
MsgBox "Please run in 64-bit Mac app"
quit
#endif
End EventHandler
End Class
Class Window1 Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
EventHandler Sub ExpandRow(row As Integer)
dim v as Variant = me.RowTag(row)
if v isa MLFeatureDescriptionMBS then
dim d as MLFeatureDescriptionMBS = v
dim t as string
Select case d.Type
case d.TypeDictionary
t = "Dictionary"
case d.TypeDouble
t = "Double"
case d.TypeImage
t = "Image"
case d.TypeInt64
t = "Int64"
case d.TypeInvalid
t = "Invalid"
case d.TypeMultiArray
t = "MultiArray"
case d.TypeString
t = "String"
end Select
List.AddRow "name", d.Name
List.AddRow "type", str(d.Type)+" "+t
dim o as string
if d.isOptional then
o = "Yes"
else
o = "No"
end if
List.AddRow "optional", o
elseif v isa Dictionary then
dim d as Dictionary = v
for each key as Variant in d.keys
dim val as Variant = d.Value(key)
if VarType(val) = Variant.TypeObject then
AddFolder key, val
else
List.AddRow key, val
end if
next
end if
End EventHandler
End Control
Control PushButton1 Inherits PushButton
ControlInstance PushButton1 Inherits PushButton
EventHandler Sub Action()
dim f as FolderItem = SelectFolder
if f <> nil then
LoadModel f
end if
End EventHandler
End Control
Control PictureButton Inherits PushButton
ControlInstance PictureButton Inherits PushButton
EventHandler Sub Action()
dim f as FolderItem = GetOpenFolderItem(FileTypes1.All)
if f = nil then Return
run f
End EventHandler
End Control
Control PicCanvas Inherits Canvas
ControlInstance PicCanvas Inherits Canvas
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect)
if pic <> nil then
dim faktor as Double = min( g.Height / Pic.Height, g.Width / Pic.Width)
// Calculate new size
dim w as Integer = Pic.Width * faktor
dim h as Integer = Pic.Height * faktor
// draw picture in the new size
g.DrawPicture Pic, 0, 0, w, h, 0, 0, Pic.Width, Pic.Height
end if
End EventHandler
End Control
Control OutputList Inherits Listbox
ControlInstance OutputList Inherits Listbox
End Control
EventHandler Sub Open()
// models are here: https://developer.apple.com/machine-learning/
// must be put in Xcode project to compile and get c variant
dim f as FolderItem = GetFolderItem("Resnet50.mlmodelc")
if f.Exists then
LoadModel f
end if
End EventHandler
Private Sub AddFolder(name as string, value as Variant)
List.AddFolder name
List.RowTag(List.LastIndex) = value
End Sub
Private Sub LoadModel(f as FolderItem)
if f.Name.Right(8) = ".mlmodel" then
dim e as NSErrorMBS
f = MLModelMBS.compileModelFile(f, e)
if e <> nil then
MsgBox "Failed to compile model."+EndOfLine+EndOfLine+e.LocalizedDescription
Return
end if
end if
// load model, to be specific: a mlmodelc folder
dim e as NSErrorMBS
dim m as MLModelMBS = MLModelMBS.modelWithContentsOfFile(f, e)
if m = nil then
MsgBox "Failed to load model."+EndOfLine+EndOfLine+e.LocalizedDescription
return
end if
// show what we know
dim d as MLModelDescriptionMBS = m.modelDescription
List.DeleteAllRows
List.AddRow "predictedFeatureName", d.predictedFeatureName
List.AddRow "predictedProbabilitiesName", d.predictedProbabilitiesName
AddFolder "inputDescriptionsByName", d.inputDescriptionsByName
AddFolder "metadata", d.metadata
AddFolder "outputDescriptionsByName", d.outputDescriptionsByName
model = m
PictureButton.Enabled = true
End Sub
Private Sub OutputAddFolder(name as string, value as Variant)
OutputList.AddFolder name
OutputList.RowTag(OutputList.LastIndex) = value
End Sub
Private Sub Run(PictureFile as FolderItem)
dim p as Picture = Picture.Open(PictureFile)
if p = nil then
break
MsgBox "Failed to load picture."
Return
end if
pic = p
PicCanvas.Refresh
// Convert to bitmap
// our test model needs smaller images, e.g. 224 width/height
// seen in Xcode: Image<BGR,224,224>
dim n as new Picture(224,224) // p.Width, p.Height)
n.Graphics.DrawPicture p, 0, 0, n.Width, n.Height, 0, 0, p.Width, p.Height
p = n
dim f as MLFeatureValueMBS = MLFeatureValueMBS.featureValueWithPicture(p)
if f = nil then
break
return
end if
dim dic as new Dictionary
dic.Value("image") = f
dim e as NSErrorMBS
dim d as new MLDictionaryFeatureProviderMBS(dic, e)
if e <> nil then
MsgBox e.LocalizedDescription
Return
end if
#if DebugBuild
'dim inputFeatureNames() as string = d.featureNames
dim inputImage as MLFeatureValueMBS = d.featureValueForName("image")
if inputImage.Type <> f.TypeImage then
break
end if
// test write image back to disk to see if it'S correct
dim c as CIImageMBS = f.CIImageValue
dim cc as Picture = c.RenderPicture
dim fff as FolderItem = SpecialFolder.Desktop.Child("input1.jpg")
cc.Save(fff, cc.SaveAsJPEG)
// test same with PictureValue
dim q as Picture = f.PictureValue
dim ff as FolderItem = SpecialFolder.Desktop.Child("input2.jpg")
q.Save(ff, q.SaveAsJPEG)
#endif
dim o as MLFeatureProviderMBS = model.predictionFromFeatures(d, e)
if e <> nil then
MsgBox e.LocalizedDescription
Return
end if
dim outputFeatureNames() as string = o.featureNames
OutputList.DeleteAllRows
for each name as string in outputFeatureNames
dim v as MLFeatureValueMBS = o.featureValueForName(name)
dim type as integer = v.Type
Select case type
case v.TypeDictionary
dim dd as Dictionary = v.dictionaryValue
OutputAddFolder name, dd
case v.TypeString
OutputList.AddRow name, v.stringValue
case v.TypeDouble
OutputList.AddRow name, str(v.doubleValue)
case v.TypeInt64
OutputList.AddRow name, str(v.int64Value)
case v.TypeMultiArray
break // TODO
case v.TypeImage
Break // TODO
case v.TypeInvalid
OutputList.AddRow name
end Select
next
Exception ne as NSExceptionMBS
Break
End Sub
Property Private Model As MLModelMBS
Property Private pic As Picture
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
FileTypes1
Filetype image/jpeg
Filetype image/png
End FileTypes1
End Project
See also:
The items on this page are in the following plugins: MBS Mac64bit Plugin.