From an image to B-UML#

BESSER also enables the definition of a Structural model from an image, for example, a picture of a hand-drawn model on a board. For this we use OpenAI’s GPT4 and you must have an OpenAI token to implement this BESSER functionality. We have selected GPT4 due to the results obtained in our experiment, however, there are still several details to improve mainly in complex models. Let’s see an example.

The following image is the hand-drawn class model representing the basic example of the Library.

Library hand draw

Warning

Please make sure your image is below 20 MB in size and is of one the following formats: [‘png’, ‘jpeg’]

To transform this image to a Structural model you can use the following code.

from besser.BUML.metamodel.structural import DomainModel
from besser.utilities import image_to_buml

library_model: DomainModel = image_to_buml(image_path="library_hand_draw.png", openai_token="****")

The function image_to_buml() has as parameters the image path and the OpenAI token, and returns the structural model library_model.

Additionally (and similar to the PlantUML to BUML transformation), the file buml/buml_model.py is generated with the structural model source code definition. You could reuse that code to modify, enhance, and recreate your structural model. The structural model source code generated by the transformation from the library_hand_draw.png model is as follows.

 1from besser.BUML.metamodel.structural import NamedElement, DomainModel, Type, Class, \
 2        Property, PrimitiveDataType, Multiplicity, Association, BinaryAssociation, Generalization, \
 3        GeneralizationSet, AssociationClass 
 4
 5# Primitive Data Types 
 6date_type = PrimitiveDataType("date")
 7int_type = PrimitiveDataType("int")
 8str_type = PrimitiveDataType("str")
 9
10# Library class definition 
11Library_name: Property = Property(name="name", type=str_type)
12Library_address: Property = Property(name="address", type=str_type)
13Library: Class = Class(name="Library", attributes={Library_name, Library_address})
14
15# Author class definition 
16Author_name: Property = Property(name="name", type=str_type)
17Author_email: Property = Property(name="email", type=str_type)
18Author: Class = Class(name="Author", attributes={Author_name, Author_email})
19
20# Book class definition 
21Book_title: Property = Property(name="title", type=str_type)
22Book_pages: Property = Property(name="pages", type=int_type)
23Book_release: Property = Property(name="release", type=date_type)
24Book: Class = Class(name="Book", attributes={Book_title, Book_pages, Book_release})
25
26# Relationships
27has: BinaryAssociation = BinaryAssociation(name="has", ends={
28        Property(name="has", type=Library, multiplicity=Multiplicity(1, 1)),
29        Property(name="has", type=Book, multiplicity=Multiplicity(0, "*"))})
30writtenBy: BinaryAssociation = BinaryAssociation(name="writtenBy", ends={
31        Property(name="writtenBy", type=Book, multiplicity=Multiplicity(0, "*")),
32        Property(name="writtenBy", type=Author, multiplicity=Multiplicity(1, "*"))})
33
34
35# Domain Model
36domain: DomainModel = DomainModel(name="Domain Model", types={Library, Author, Book}, associations={has, writtenBy}, generalizations=set())

From an image to PlantUML#

Similarly, it is also possible to obtain the PlantUML code from a model in an image, as follows.

from besser.utilities import image_to_plantuml

plantUML_model: str = image_to_plantuml(image_path="library_hand_draw.png", openai_token="****")
print(plantUML_model)

The result of this transformation is a string with the code specified in the PlantUML notation:

@startuml

class Library {
    name: str
    address: str
}

class Book {
    title: str
    pages: int
    release: date
}

class Author {
    name: str
    email: str
}

Library "1" -- "*" Book : has
Book "*" -- "1..*" Author : writtenBy

@enduml