Documente Academic
Documente Profesional
Documente Cultură
Supervisor Candidate
Prof. Paolo PRINETTO Iman AMIRTAHERI
Internship Tutors
Dr. Giulio GAMBARDELLA
Dr. Francesca BALESTRA
July 2016
Abstract
Tire industries have an annual total sale of approximately $32.1 billion. This number
itself shows how big is this market. Costumers usually buy car tires directly from auto
repair centers. So a tool that helps auto repairmen to sell their tires more effectively is
extremely valuable. Tire Profiles Italy company has designed two different solutions for
this purpose. Both of these devices detect the necessity of tire replacement by means
of scanning tire thread depth. Another important item that should be paid attention
to, is the expiry date of tire. This date is usually calculated based on production date.
According to the department of transportation regulations, tire producers are obliged to
emboss or engrave the production week and year in a structured code on the tire sidewall.
This code is also called as DOT code. So Tire Profiles Italy company introduced a new
project to design a device for DOT code scanning. There were several options about how
this device should scan the code technically. Among possible choices, the solution with 3D
laser sensor was selected. In this approach the laser sensor measures distances between all
points of a line and laser sensor itself. By moving sensor in a trajectory perpendicular to
its laser beam axis, it can scan the whole portion of tire. This thesis is mainly focused on
design and build a communication interface for this laser sensor in order to provide the
infrastructure for PC and laser sensor to communicate. At the next step, thanks to this
communication channel, a software for DOT code scanning is developed which performs
acquisitions and stores the corresponding data in a host PC. As a complementary study,
image pre-processing techniques are implemented in MATLAB and Qt plus Open-CV
framework.
ii
Contents
Abstract ii
List of Tables v
List of Figures vi
1 Introduction 1
1.1 General Tire Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Tire Specification Code . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 Department of Transportation (DOT) Safety Code . . . . . . . . . . 2
1.1.3 Uniform Tire Quality Grading (UTQG) Code . . . . . . . . . . . . . 2
1.2 Tire Replacement Symptoms . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 Tire Treads Depth . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2 Tire Expiry Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Laser Sensor 11
3.1 Functional Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.1 Distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.2 Height . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.3 Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 Communication Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 Time Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 Communication Interface 21
4.1 Micro-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1.1 General Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.2 Pin Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.1.3 Universal Synchronous Asynchronous Receiver Transmitter (USART) 23
iii
4.2 RS485 Transceiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.3 USB to Serial Converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 Hardware Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.5 Software Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6 PC-Sensor Communication Test . . . . . . . . . . . . . . . . . . . . . . . . . 30
5 Acquisition Software 33
5.1 LaserSensor Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.2 MainWindow Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6 Image Pre-Processing 43
6.1 MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2 Qt and Open-CV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
7 Conclusion 63
Bibliography 65
Appendices 66
A Micro-controller C Code 67
iv
List of Tables
v
List of Figures
1.1 Tire Specification Code Sample: This code contains tire technical information. 1
1.2 DOT Code Sample: All safety information is gathered inside this universal
code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 UTQG Code Sample: This code contains tire grades in three different subjects. 3
1.4 Tire Tread Depth: Tire producers recommend to replace tires with less than
10% life time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Groove Glove Scanner: Handheld device to measure tire tread depth and
identify cars license plate. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6 TreadSpec (PRT Scanner): Tread depth scanner which has to be installed
on the ground. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1 Fixed Illumination: Naive approach to illuminate tire surface and capture
DOT code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Variable Illumination: Camera captures every time that illumination changes. 8
2.3 Laser Sensor: Creates a distance profile line by line. . . . . . . . . . . . . . 9
3.1 Sensor Installation Methods: a) Standard Installation b) Angled Installation 12
3.2 Sensor Distance Measurements: Average, Maximum and Minimum . . . . . 13
3.3 Sensor Height Measurements: Average, Maximum, Minimum and Delta . . 13
3.4 Laser Sensor Coordinates: It creates a matrix of x and z elements for every
acquisition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5 RS485 Connection Diagram: This protocol can connect 15 sensors to a
master. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.6 RS485 Pin Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.7 Laser Sensor Timing (Time Flows) . . . . . . . . . . . . . . . . . . . . . . . 17
4.1 General Connection Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 ATMega16 Pin Configurations . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.3 MAX485 Pin Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 USB to Serial Converter Module . . . . . . . . . . . . . . . . . . . . . . . . 25
4.5 Communication Interface Connection Scheme . . . . . . . . . . . . . . . . . 25
4.6 TeraTerm Terminal Emulator Serial Settings . . . . . . . . . . . . . . . . . 30
4.7 PC-Sensor Communication Test . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.8 RS485 Communication Interface . . . . . . . . . . . . . . . . . . . . . . . . 31
5.1 DOT Code Recognition Software (DCR) v1 . . . . . . . . . . . . . . . . . . 33
5.2 Signal Slots Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.1 MATLAB Loading Raw Data File . . . . . . . . . . . . . . . . . . . . . . . 45
vi
6.2 MATLAB 3D Surface Representation . . . . . . . . . . . . . . . . . . . . . . 46
6.3 Leveled Surface Representation . . . . . . . . . . . . . . . . . . . . . . . . . 47
6.4 MATLAB 3D Model Abrupt Changes . . . . . . . . . . . . . . . . . . . . . 48
6.5 MATLAB 3D Model Added Neighbors . . . . . . . . . . . . . . . . . . . . . 49
6.6 MATLAB 3D Model Removed Min Value . . . . . . . . . . . . . . . . . . . 50
6.7 Segmented Black & White Image . . . . . . . . . . . . . . . . . . . . . . . . 52
6.8 Segmented Grayscale Image . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.9 Contrast Stretched Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.10 Negative Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.11 Open-CV Loaded File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.12 Open-CV Orientation Corrected . . . . . . . . . . . . . . . . . . . . . . . . 59
6.13 Open-CV Colors Inverted . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.14 Open-CV Edges Sharpened . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
vii
Chapter 1
Introduction
This thesis report documents general information about vehicle tire codes, specifically tire
DOT code and its importance. Then different approaches for DOT code scanning are
analyzed and one of them is chosen. In the rest of this report, the selected approach is
documented, a communication interface is designed and built, a C++ software is developed
for data acquisition and at the end, some image pre-processing methods are performed.
Figure 1.1. Tire Specification Code Sample: This code contains tire technical information.
1
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Figure 1.2. DOT Code Sample: All safety information is gathered inside this universal code.
DOT codes may consist of 8 upto 13 characters. Depending on the coding that manufac-
turer uses, the embedded information varies but in any case some important data has to
be documented. Some of these information fields are gathered in table 1.1.
2
1 Introduction
this code.[1]
Figure 1.3. UTQG Code Sample: This code contains tire grades in three different subjects.
3
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
producers recommend costumers to change tires as soon as the tire treads depth fall less
than 2/32-inch (1.6mm). Figure 1.4 shows corresponding life time for each level of treads
depth. [2]
Figure 1.4. Tire Tread Depth: Tire producers recommend to replace tires
with less than 10% life time.
From longtime ago tread depth measurement was performed by means of length measure-
ment devices such as calipers. Even many of auto repairmen use a small coin to measure
depth. Although this kind of approach is not wrong and use the same principle but it is
not accurate enough because it is necessary to measure and check precisely not only for a
single spot of tire but also for all of its surface. So the accurate procedure is very time
consuming for an auto repairman to follow.
Tire Profiles Italy Srl. company has designed two different solutions to measure treads
depth.
TreadSpec
TreadSpec also known as PRT Scanner is a device which requires a solid structure to
mount on the ground surface. This solution is usually used on the entry point of auto
service centers and allows the driver to drive over it. In many cases people pay service
centers a visit just to change oil or diagnose an error, with this scanner installed in
the entrance, service centers generate a full report about tire tread depth and its
alignment. Hence, this device can boost their sale effectively. Figure 1.6 shows two
4
1 Introduction
Figure 1.5. Groove Glove Scanner: Handheld device to measure tire tread depth
and identify cars license plate.
Figure 1.6. TreadSpec (PRT Scanner): Tread depth scanner which has to be
installed on the ground.
5
6
Chapter 2
So far, the reasoning behind necessity to design and make a device to scan DOT code
has been documented. From now on, two different approaches are analyzed and then in
following chapters, preferred approach is designed from hardware and software point of
views.
In order to have a complete vision of whole design process, primarily design requirements
are gathered in this way.
Connect to cloud for storing raw scanned data and fetch processed data after com-
pletely processed.
According to this general design requirements many approaches came into mind. The
most important matter that affects the whole design process is that with which technology
this device has to perform scanning process. Two different solutions were proposed.
7
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Figure 2.1. Fixed Illumination: Naive approach to illuminate tire surface and
capture DOT code.
This prototype masks the ambient light thanks to its method of usage which is touching
tire surface. Instead, it has many infrared diodes to illuminate the DOT code when it
captures the photo. Since these illumination lamps are turned on and off simultaneously
and the camera axis is perpendicular to tire surface, it is not possible to distinguish
characters since tire codes are embossed or raised on the body of tire and it is a black on
black pattern.
Figure 2.2. Variable Illumination: Camera captures every time that illumination changes.
8
2 DOT Code Scanning
In order to make a comparison between new approach and the previous one, table 2.1 is
created with pros and cons of this new approach. By considering this comparison table,
the best approach is to use camera scanning with variable illumination but because the
engineering part of Tire Profiles Italy company has already defined the project with laser
sensor, this thesis focused on laser scanning. Following chapters are dedicated to introduce
the laser sensor and its features, design an interface for communication with it, design an
user interface to connect to the sensor and perform acquisition, design a protocol to save
measurement data, and try to perform some simple image processing techniques to improve
the scanned data.
9
10
Chapter 3
Laser Sensor
So far, the desired design approach is selected. In this chapter, the laser sensor is in-
troduced, its features are documented and an appropriate communication interface is de-
signed. Sensor selection is another decision which was imposed by the Tire Profiles Italy
company. For administrative and economical reasons, this sensor was already selected and
purchased for this project.
3.2 Installation
According to sensors datasheet provided by Baumer company [6], it can be installed in
two different methods.
Standard Installation
In this configuration sensor is mounted at a right angle with respect to the surface.
11
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Angled Installation
When space condition does not allow to install sensor in standard configuration it
is possible to tilt sensor upto 30 from the perpendicular reference line. In this case
also, object has to lie within the functional criteria. Note that in this configuration
distance function of sensor does not work and only height function is accessible.
For the purpose of DOT code scanning it is the best to use standard installation since
always there is enough space for auto repairman to hold the scanner device perpendicular
to the tire sidewall surface. Final design should consider a method to satisfy function
range of 10 upto 15 cm of device for all scanning process. There are two different solution
to ensure this device always lie in the correct range.
Warn auto repairman when the device is approaching to its functional range limits.
For example two LEDs or a single buzzer may be considered as the method of
notification.
Device housing can be designed such a way that when it touches tire sidewall there is
a distance of 12.5cm between laser sensor and DOT code. In this way auto repairman
should ensure that there is a contact between device and tire during the scan process.
Since this decision is not a matter of current thesis, it is left for other engineers to decide.
3.3 Functions
This sensor supports three different functions.
12
3 Laser Sensor
3.3.1 Distance
To perform distance measurement it is required to send corresponding command and
choose the desired option. Sensor basically measures the distance between itself and all
points lying in the scanned line. Then it finds the minimum, maximum and also the
average of these measured distances. According to the sent command it responds with one
of these three values. Figure 3.2 depicts these three different measurements on a sample
surface.
3.3.2 Height
Similar to the Distance function, Height function can be selected by sending appropriate
command and attaching desired measurement type. Same as the previous case, sensor first
measures all points to sensor distances and then perform selected operation. Specifically for
Height function all measurements are taken with respect to a hypothetically defined plane
called reference. This plane must be taught to sensor through a certain procedure. Height
command can return minimum, maximum or average distance between line points and
reference plane. There is also another option called delta height which returns maximum
difference between points altitude. Figure 3.3 depicts the purpose of each described option.
Figure 3.3. Sensor Height Measurements: Average, Maximum, Minimum and Delta
13
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
3.3.3 Profile
As described in the two previous functions, this laser sensor always measures the distance
between itself and all points in the scanned line. These measurements are stored in a
matrix format. Figure 3.4 depicts these coordinates on a sample object and table 3.2
denotes a blank profile matrix.
This function is only accessible when device is in diagnose mode. Since for a 4cm field
of view, it is necessary to transmit about 400 (x,z) pairs, this mode is dramatically slower
than previous modes.
Although this mode of function is slower than the others, but this is the only way to
capture all measurements and build the tire altitude profile. So this mode of operation
is selected and since it only works in diagnose mode, almost all other functions are not
accessible at the same time.
14
3 Laser Sensor
not at the same time. Full duplex mode defines a similar connection but with capability
to send and receive simultaneously. This protocol requires two wires for half duplex mode
and four wires for full duplex transmission. According to Baumer sensors datasheet, fig-
ure 3.5 shows required configuration in order to connect upto fifteen sensors to a master.[7]
Figure 3.5. RS485 Connection Diagram: This protocol can connect 15 sensors to a master.
The most important features of this topology are listed in this way.
Master is the only member of this configuration which can initiate a request. Sensors
are slaves, so they do no transmit anything unless master asks for it.
There are two failsafe resistors called RB to define the resistance level when no
transmitter is active.
Since there is only one sensor to work with, first topology is selected for communication.
This sensor came with a default shielded cable. Figure 3.6 denotes corresponding pin
diagram for this cable.
The suggested voltage supply for this sensor is 24v. Also it is recommended to connect
15
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
16
3 Laser Sensor
1. 38400 bits/s
2. 57600 bits/s
3. 115200 bits/s
The default configuration for baud rate is 57600 bits/sec. It means that every time that
sensor is powered on, it automatically interprets incoming requests with baud rate of
57600. Also it is possible to change this value with corresponding command and save it
to configuration flash.
Since the application goal is to make acquisition with the highest possible rate, the sensor
timing to response the request is very crucial. Figure 3.7 denotes various timing variables
and table 3.3 determines their values.
Since the application must use the sensor in diagnose mode, the maximum time re-
quired by sensor to process the request and prepare appropriate response can be derived
as follows.
To make a rough calculation about order of acquisition rate, lets assume that field of
view attribute is set to 4cm. In other words, laser sensor is scanning only line with width
of 4cm per each acquisition iteration. According to table 3.2 on page 14, laser sensor
returns a pair of x and z elements for each 0.5mm of field of view.
4cm
Total number of pairs = 0.5mm = 80
17
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
By combining information from this calculation and previous one, table 3.4 denotes timing
values for an acquisition with field of view equal to 4cm.
To have a rough calculation, it is assumed that laser sensor requires 100 ms (half of
maximum value) to perform measurement and prepare appropriate data. Acquisition pe-
riod = 100 + 44.4 + 0.1 = 144.5ms
1
Final acquisition rate = 144.5m = 6.92Hz
With this calculation its quite clear that this acquisition rate is low, for better under-
standing this matter here is an example. Lets assume it is required to make acquisition
every time that red line moves 1mm (half precision with respect to x axis). According to
the calculated acquisition rate, it is possible to derive,
M ovementDistance 1mm
Movement speed of laser sensor = M ovementT ime = 144.5m = 6.92mm/sec
In other words, if sensor is moved with speed of 7mm/sec (less than 1cm/sec), the acquired
data precision in y axis will be half of x axis precision. Now it is more observable that
18
3 Laser Sensor
this laser sensor is not suitable for the real action, but since this sensor has been already
purchased, the prototype designing was based on this sensor.
3.6 Commands
In previous sections, all important features of laser sensor and its communication rules
were analyzed. In this section, relevant commands are listed and described. Every single
command has to have a predefined structure in order to be decode-able for laser sensor.[7]
Command structure consists of following ordered items:
Start identifier: A simple colon character ":" is used to acknowledge beginning of a
command.
Device address: Two digits have the responsibility to determine target device ID.
All sensors have address equal to 01 at power on instant. In order to have more than
one sensor in a network, sensors ID must be configured one by one such a way that
there will be no conflict among them.
Payload: This part of command can have different number of characters depending
on the command format. Payload itself consists of:
Index: This item has three characters and form a number. Every single com-
mand which is supported by laser sensor has an ID called index. To perform a
desired operation, command must specify the corresponding index. Note that
it is possible for a single index to support both write and read operations.
Separator: A semicolon character ";" is used before and after of each payload
element to clarify elements from each other.
Payload element: If the desired command requires a payload element (data) to
perform operation, desired data should be placed in payload element. Note that,
it is possible to have many payload elements separated by semicolon separator.
Termination characters: A combination of carriage return "\r" and line feed "\n"
characters is used to determine the commands end. The same characters are used
to represent a new line in Microsoft Windows operating systems.
Most of laser sensors in the category of "MESAX multi-distance measuring" have a
built in display and user input. This specific sensor does not have this feature because
there is no intention to interact with the laser sensor directly. With this introduction, all
19
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
of these sensors are locked in the sense that it is not possible to communicate with them
via RS485 protocol unless they receive a specific command to unlock themselves.
Command to unlock RS485 communication port: ":01W010;0;E9C3\r\n"
Note that this command should be sent by baud rate equal to 57600 bits/sec.
20
Chapter 4
Communication Interface
So far, laser sensor characteristics and its features have been analyzed. In order to perform
the communication with this device, first it is necessary to define what is the final device
which requires to communicate with laser sensor. Since data acquisition should be made
by a computer, the final device is computer. But according to the design requirements
listed on page 7, this communication should be wireless. So its a wise choice to add a
micro-controller between this connection to regulate the connection and also to create the
infrastructure for further wireless module addition. Note that adding wireless module was
not a part of this thesis and it is left for further improvements. Figure 4.1 depicts the
general connection diagram considered so far. More detailes will be added during this
chapter.
4.1 Micro-Controller
There were different choices for micro-controller device. From a simple Arduino board
till more complicated boards like Raspberry pi series, all of them could satisfy device
requirements but with a glance to the mass production requirements, it was more rational
to use a micro-controller integrated circuit instead of working with a board. One of the
most famous and easy to use family of micro-controllers are AVR produced by Atmal
company. To choose between micro-controllers residing in this family, there were a few
21
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
points to consider:
Output levels of micro-controller must use TTL logic, because RS485 uses TTL logic
for each wire otherwise there is a need for level shifter.
It is recommended to have SPI port for further wireless module or gyroscope addition.
In order to work with the highest possible baud rate, micro-controller has to be able
to work with 11.0592MHz clock. This clock assures that UART/USART communi-
cation error will be less than 0.0%.
According to these requirements, ATMega16 micro-controller was the selected choice
among AVR micro-controllers. In the rest of this chapter, technical relevant characteristics
of this device are documented.[9]
Peripheral features
The micro-controller used for this project was packaged in DIP format because in this way
it is much easier to use it on bread board.
22
4 Communication Interface
Figure 4.2 denotes pin configurations for ATMega16 micro-controller. Some of pins have
dual functions and they can be selected by software. For example pin #14 is the IO #0
of port D in normal condition. It can be configured to function as serial receiver also.
In order to manage the RS485 connection between PC and the laser sensor, micro-
controller has to work with its USART block. According to the pin configurations on
figure 4.2, table 4.1 denotes all USART related pins.[9]
23
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
24
4 Communication Interface
so a USB cable can connect it to PC. There are also five pins which three of them deliver
GND, 3.3V and 5V and the two remaining form the serial connection wires (Rx and Tx).
This is not a complicated module, most of USB to Serial converters make use of PL2303
chip for data conversions.[11]
In this scheme, PC which is the final device to send commands to laser sensor and
receive response from it, is connected to USB to Serial converter via a simple USB cable. So
in the PC, by installing appropriate driver, it is possible to open a COM port and transmit
serial data. Commands sent by PC are delivered to micro-controller. Micro-controller has
the responsibility to control RS485 connection. This control means that, if there is a
command to be delivered to laser sensor, micro-controller prepares the line by setting DE
to "1" and RE to "0". In this way line is ready to accept value from micro-controller. While
this situation exists, the command is sent to laser sensor. Micro-controller will change the
line situation immediately after sending is finished. In this way the command is sent and
line is ready to receive answer from laser sensor. After computation time required by
25
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
laser sensor, response will be sent back and since the line is tuned to deliver data from
laser sensor to PC, the response propagates through MAX485 and directly reaches USB to
serial and then PC. According to this scheme, tables 4.2,table 4.3,4.4 and 4.5 summarized
are required connections for USB to Serial module, micro-controller ATMega16, MAX485
transceiver and laser sensor respectively.
26
4 Communication Interface
27
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Databits: 8
Startbit: 1
Stopbit: 1
Parity: Even
Sender/Receiver Interrupt: No
Now that the micro-controller is all set, it is necessary to discuss about its duty.
As it has been said earlier, micro-controller should define lines situation by constantly
monitoring the PC output. If the output has the character ":", micro-controller sets its
pin #6 of port D to "1" and then puts the same character on its serial output which is
connected to laser sensor through MAX485. Also a local protocol is considered that PC
should send a special character with ascii code of 0x0B to micro-controller to acknowledge
28
4 Communication Interface
command termination. So each command starts with ":" and ends with 0x0B character.
After receiving ":" character, micro-controller outputs the received data till termination
character (0x0B) receipt. At this point, micro-controller toggles line situation by setting
port D pin #6 to "0". In this way, after enough processing time, laser sensor sends the
corresponding response back to the PC without micro-controller interference. Listing 4.3
contains above explained code. Since micro-controller should constantly run this program,
this code portion is placed in an always true loop.
1 while (1)
{
3 ch=g e t c h a r ( ) ;
i f ( ch== : )
5 {
PORTD. 6 = 1 ;
7 p u t c h a r ( ch ) ;
}
9 e l s e i f ( ch==0x0B )
{
11 f o r ( i =0; i <100; i ++) ;
PORTD. 6 = 0 ;
13 }
else
15 p u t c h a r ( ch ) ;
}
As previously mentioned, laser sensor can operate with three different baud rates and
the default one is not the fastest one. Although it is possible to change the baud rate and
store it in the configuration flash of laser sensor, for the sake of maintenance and plug and
play integrity, the micro-controller code is designed to change baud rate to the fastest one
upon system power up. With this option, PC program always send required commands
with baud rate equal to 115200 bits/sec and micro-controller has the duty to change laser
sensor and also its own baud rate at first place.
PORTD. 6 = 1 ;
2 c r=0x0D ;
cn=0x0A ;
4 delay_ms ( 2 0 0 0 ) ;
p r i n t f ( " : 0 1 W010 ; 0 ; %c%c " , cr , cn ) ;
6 delay_ms ( 1 0 0 ) ;
p r i n t f ( " : 0 1 W006 ; 2 ; %c%c " , cr , cn ) ;
8 delay_ms ( 1 0 0 ) ;
UBRRL=0x05 ;
In this code portion, first, communication line gets ready for command transfer, then
after a delay of 2 seconds, micro-controller unlocks the RS485 lock, changes laser sensor
baud rate and then changes its own baud rate to 115200 bits/sec. Delays are considered
due to laser sensor power up latency and MAX485 propagation time.
29
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
By hitting OK, COM port opens and now everything is ready to send a command
to laser sensor and wait for response without having concerns about RS485 protocol or
anything else. Figure shows a sample command and its corresponding response communi-
cated between PC and Laser Sensor. In this communication, PC sent a request to unlock
RS485 lock.
Figure 4.8 shows the final version of RS485 communication interface functioning. On
30
4 Communication Interface
the left side, there is the power supply which has 5V and 24V voltage sources. On the
right side there are microcontroller, MAX485 and USB to serial converter.
31
32
Chapter 5
Acquisition Software
In previous chapter, a communication interface was designed and built to make PC-Sensor
communications possible. A sample command sent by means of TeraTerm terminal emula-
tor and corresponding responses received. In this chapter, the goal is to design a software
to automate this process. So the software should be able to initiate a connection to the
laser sensor, send requests, receive responses, display them in a graphical way and store
them in a file for further usage.
In order to have possibility to compile the program for different operating systems and
also for accessing to simpler features, Qt IDE has been used for software development.
Qt IDE is developed and supported by Nokia company. Nowadays many programmers
and developers use Qt for software development. Figure 5.1 depicts the first version of
acquisition program designed. During rest of this chapter different program sections will
be analyzed.[12]
Qt IDE supports signals and slots methodology for objects communication. During
33
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
software design process, it was decided to create a class for laser sensor communication,
so this class could be imported to any other applications for development. In this case,
the object created of this type can use signals and slots for communication or it can be
used in an ordinary way. To proceed with thesis report, two different classes are analyzed
independently. One class called "LaserSensor" is dedicated to sensor communications and
another class called "MainWindow" is for user interface.
34
5 Acquisition Software
void ReadProfile () ;
37 void WriteStoreConfigurationCommand ( i n t C o n f i g ) ;
void WriteResetToFactorySettingsCommand ( i n t Command) ;
39 void CloseConnection ( ) ;
void SampleNoChanged ( QString SampleNumber ) ;
Listing 5.1. LaserSensor Class Private Slots
Despite from these available slots, a LaserSensor object can emit signals. Signals can
be used in order to send the appropriate response back to the original program. Figure
5.2 depicts an example of this approach. Listing 5.2 lists all declared signals for this class.
signals :
2 void A v a i l a b l e P o r t s ( i n t TotalNumber , QVector<QString> P o r t s ) ;
void ConnectionStatus ( bool Status ) ;
4 void ApplicationError ( int ApplicationError ) ;
void VendorID ( i n t Vendor_ID ) ;
6 void VendorName ( QString Vendor_Name ) ;
void DeviceID ( i n t Device_ID ) ;
8 void VariantID ( i n t Variant_ID ) ;
void SensorType ( QString Sensor_Type ) ;
10 void SerialNumber ( QString Serial_Number ) ;
void BusAddress ( i n t BusAddressValue ) ;
12 void BaudRate ( i n t BuadRateValue ) ;
void RS485Lock ( b o o l Switch ) ;
14 void TouchButtonLock ( b o o l Switch ) ;
void MeasurementType ( QString Type ) ;
16 void MeasurementValue ( f l o a t MeasurementValue , QString Q u a l i t y ) ;
void Average ( QString a v e r a g e ) ;
18 void Max ( QString max) ;
void Min ( QString min ) ;
20 void D e l t a ( QString d e l t a ) ;
void S t a n d a r d D e v i a t i o n ( QString s t a n d a r d d e v i a t i o n ) ;
22 void Q u a l i t y ( QString q u a l i t y ) ;
void FieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
24 void ObjectType ( QString ObjectType ) ;
void P r e c i s i o n ( QString P r e c i s i o n ) ;
26 void LaserOffDataHold ( b o o l Switch ) ;
void FlexMountEnable ( b o o l Switch ) ;
28 void SetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
35
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
The third line of code has the duty to register a meta type in order to provide
possibility to move an object of this class to a new thread. DeviceAddress variable
is always one since there is only one sensor in RS485 network. Yindex is the index
of scanned lines and it is set to zero at first. After each successful acquisition it will
be automatically incremented. filecreated flag is used to check if the profile text file
is created or not. In read profile mode, laser sensor class should store acquisition
data in a text file. SampleNo variable is defined to identify different tire samples. It
is just there for further result comparisons.
FindAvailablePorts
This function scans for all COM ports, then removes those ones that are not available.
A COM port is not available when another program is using it and it is flagged as
busy. Then it emits a signal containing total number of available ports and their
names. Listing 5.4 denotes corresponding codes.
void LaserSensor : : FindAvailablePorts ( )
36
5 Acquisition Software
2 {
i n t TotalNumber =0;
4 QVector<QString> P o r t s ( 0 ) ;
f o r e a c h ( c o n s t Q S e r i a l P o r t I n f o &i n f o , Q S e r i a l P o r t I n f o : :
availablePorts () )
6 {
i f ( ! i n f o . isBusy ( ) )
8 {
P o r t s . append ( i n f o . portName ( ) ) ;
10 TotalNumber++;
}
12 }
emit A v a i l a b l e P o r t s ( TotalNumber , P o r t s ) ;
14 }
Listing 5.4. FindAvailablePorts: Returns all ready to connect COM ports
SendCommand
All slots use a function to send a command to laser sensor. SendCommand receives
a string as input, then adds other necessary elements to its begin and end according
to the RS485 command structure. Listing 5.5 contains corresponding codes.
v o i d L a s e r S e n s o r : : SendCommand ( QString Command)
2 {
QChar c r=0x0D ;
4 QChar cn=0x0A ;
QChar s t o p c h a r=0x0B ;
6 QString ToSend=" : " ;
ToSend . append ( QString ( "%1" ) . a r g ( DeviceAddress , 2 , 1 0 , QChar ( 0 ) ) ) ;
8 ToSend . append (Command) ;
ToSend . append ( " ; " ) ;
10 ToSend . append ( " " ) ;
ToSend . append ( c r ) ;
12 ToSend . append ( cn ) ;
ToSend . append ( s t o p c h a r ) ;
14 s e r i a l >w r i t e ( ToSend . t o L a t i n 1 ( ) ) ;
}
Listing 5.5. SendCommand: Prepares command and sends it.
In this function start, carriage return, line feed and stop char has been defined. Stop
char is the conventional character 0x0B that informs micro-controller to change the
RS485 line mode. After command preparation, it will be sent byte by byte to serial
port thanks to the toLatin1 method of QString class.
ReceiveResponse
This function is intended to be called by each slot after SendCommand execution.
In this way, the function will be blocked until a response is received or a time-out
occurs. Listing 5.6 gathers all necessary codes for this purpose. This function returns
true in case of response receipt and false in case of time-out.
37
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
This code makes use of serial library time-out ability. If no new byte is received
within 500msec, if statement will be false and function returns false, acknowledging
that the request has been timed-out so the main function should request it again.
If a byte is received, it will be added to Response variable and cleared from serial
buffer. The while loop remains true, until the line feed character receipt. After
successful command receipt, function splits it to payloads. Usually sensor responses
have payloads to return measurement values.
WriteDiagnoseMode
As previously mentioned about working with profile command of laser sensor, this
command is only available when laser sensor is in diagnose mode. So the WriteDi-
agnoseMode has the duty to enter laser sensor to this mode. Listing 5.7 denotes
corresponding functions.
1 v o i d L a s e r S e n s o r : : WriteDiagnoseMode ( b o o l Switch )
{
3 SendCommand ( "W030; 20;20 " ) ;
ReceiveResponse ( ) ;
5 SendCommand ( " R030 " ) ;
ReceiveResponse ( ) ;
7 SendCommand ( "W050 ; 1 " ) ;
i f ( ReceiveResponse ( ) )
9 {
emit DiagnoseMode ( t r u e ) ;
11 }
38
5 Acquisition Software
}
Listing 5.7. WriteDiagnoseMode: Activates diagnose mode.
Although this function is designed to just activate the diagnose mode, it also sets the
field of view range. In third line, laser sensor is asked to set its measuring range from
-20mm to 20mm with respect to the center of red beam. Then the same attribute
requested to read for verification. Finally at line 7, program sends diagnose mode
activation command and if the response is received, it emits a signal to MainWindow
which yields to a check in a checkbox.
ReadProfile
Finally, its time to analyze the main function that collects acquisition data. This
function creates two data files and store the same content into both of them. The
reason of creating two identical files is that, for image pre-processing part, it was
necessary to address a constant file name in MATLAB. In order to prevent from
overwriting the previously made acquisition, another file with date, time and also
sample number is created each time. According to listing 5.8, this function performs
a profile acquisition once and emits a ProfileReady signal when its done. This is the
duty of MainWindow to call this function in a loop to scan multiple lines.
void LaserSensor : : ReadProfile ( )
2 {
if (! filecreated )
4 {
QDateTime c u r r e n t d a t e a n d t i m e = QDateTime : : currentDateTime ( ) ;
6 P r o f i l e D a t a . s e t F i l e N a m e ( " Pr ofil eData _Sam ple "+SampleNo+"_"+
c u r r e n t d a t e a n d t i m e . t o S t r i n g ( " yyyyMMdd_hhmms s " )+" . t x t " ) ;
P r o f i l e D a t a . open ( QIODevice : : WriteOnly ) ;
8 ProfileData1 . setFileName ( " P r o f i l e D a t a . txt " ) ;
P r o f i l e D a t a 1 . open ( QIODevice : : WriteOnly ) ;
10 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
P r o f i l e S t r e a m << "Y\tX\ t \Z " <<e n d l <<e n d l ;
12 P r o f i l e S t r e a m 1 . s e t D e v i c e (& P r o f i l e D a t a 1 ) ;
P r o f i l e S t r e a m 1 << "Y\tX\ t \Z " <<e n d l <<e n d l ;
14 f i l e c r e a t e d=t r u e ;
}
16 SendCommand ( " R052 " ) ;
i f ( ReceiveResponse ( ) )
18 {
Q S t r i n g L i s t XZMeasurements ;
20 XZMeasurements=Payloads [ 1 ] . s p l i t ( " " ) ;
i n t TotalMeasurements=XZMeasurements [ 0 ] . t o I n t ( ) ;
22 XZMeasurements . r e m o v e F i r s t ( ) ;
Yindex++;
24 f o r ( i n t i =0; i <TotalMeasurements / 2 ; i ++)
{
26 P r o f i l e S t r e a m << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t
" <<XZMeasurements [ 2 i +1] <<e n d l ;
P r o f i l e S t r e a m 1 << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \
t " <<XZMeasurements [ 2 i +1] <<e n d l ;
39
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
28 }
30 }
emit P r o f i l e R e a d y ( ) ;
32 }
Listing 5.8. ReadProfile: Makes profile acquisition once.
This function primarily checks for file existence, if it is not created, it creates two files
as described above. Then it prints column headers into these two files. After that
a command with read profile index will be sent to laser sensor and upon successful
receipt, it splits (x,z) pairs and prints them along corresponding y index into both
files. Listing 5.9 shows 10 lines of an acquisition data file with 10534 lines.
Y X Z
2
1 0 3889
4 1 50 3897
1 100 3911
6 1 150 3955
1 200 3966
8 1 250 3953
1 300 3971
10 1 350 4006
Listing 5.9. Read Profile Sample
Note that the thread should be started before program execution, but this will happen
after signal and slots connections definition. So next part should define the signal and
slots connection. This process is like wiring building blocks. Listing 5.11 lists all of these
connections.
1 // Find A v a i l a b l e P o r t s
40
5 Acquisition Software
5 // I n i t i a l i z e Connection
c o n n e c t ( t h i s , SIGNAL( I n i t C o n n e c t i o n ( QString ) ) , Sensor , SLOT( I n i t C o n n e c t i o n
( QString ) ) ) ;
7 c o n n e c t ( Sensor , SIGNAL( C o n n e c t i o n S t a t u s ( b o o l ) ) , ui>S e r i a l _ S t a t u s , SLOT(
s e t C h ec k ed ( b o o l ) ) ) ;
9 // Vendor I n f o r m a t i o n
c o n n e c t ( ui>GetVendorInfo , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( ReadVendorInfo ( )
));
11 c o n n e c t ( Sensor , SIGNAL( VendorID ( i n t ) ) , ui>VendorID_Label , SLOT( setNum ( i n t
)));
c o n n e c t ( Sensor , SIGNAL( VendorName ( QString ) ) , ui>VendorName_Label , SLOT(
s e t T e x t ( QString ) ) ) ;
13
// D e v i c e I n f o r m a t i o n
15 c o n n e c t ( ui>G e t D e v i c e I n f o , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( R e a d D e v i c e I n f o ( )
));
c o n n e c t ( Sensor , SIGNAL( DeviceID ( i n t ) ) , ui>DeviceID_Label , SLOT( setNum ( i n t )
));
17 c o n n e c t ( Sensor , SIGNAL( VariantID ( i n t ) ) , ui>VariantID_Label , SLOT( setNum (
int ) ) ) ;
c o n n e c t ( Sensor , SIGNAL( SensorType ( QString ) ) , ui>SensorType_Label , SLOT(
s e t T e x t ( QString ) ) ) ;
19 c o n n e c t ( Sensor , SIGNAL( SerialNumber ( QString ) ) , ui>SerialNumber_Label , SLOT
( s e t T e x t ( QString ) ) ) ;
41
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
37 // Read P r o f i l e P e r i o d i c a l l y
c o n n e c t ( ui>R e a d P r o f i l e , SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( R e a d P r o f i l e ( ) ) ) ;
39 c o n n e c t ( Sensor , SIGNAL( P r o f i l e R e a d y ( ) ) , Sensor , SLOT( R e a d P r o f i l e ( ) ) ) ;
c o n n e c t ( ui>spinBox , SIGNAL( valueChanged ( QString ) ) , Sensor , SLOT(
SampleNoChanged ( QString ) ) ) ;
41
// C l o s e Connection
43 c o n n e c t ( ui>STOP, SIGNAL( c l i c k e d ( ) ) , Sensor , SLOT( C l o s e C o n n e c t i o n ( ) ) ) ;
45 SensorThread>s t a r t ( ) ;
Listing 5.11. Signal-Slot Connections
These connections, connect user interface elements signals such as clicked() to a slot
in sensor object. Then it connects a relevant signal of sensor to a slot of user interface
element. For example a click on Connect button in user interface, will cause a request
to laser sensor device to remove its RS485 lock and upon successful operation, a check
will appear in user interface communication status checkbox. This concept is depicted on
figure 5.2 on page 35. After providing all connections, thread is started on line 45.
42
Chapter 6
Image Pre-Processing
6.1 MATLAB
In many similar cases, when the goal is to perform image processing techniques and have
OCR program, the starting point is to use MATLAB software because it offers many easy
to use functions which are already developed. In this section a .m program is analyzed
step by step to determine how does it work.
Step 1: Listing 6.1 represents a portion of code dedicated to open the data file, fill three
x,y and z vectors based on imported data and draw a 3D object to represent scanned
tire portion.
1 %Read measured data from data f i l e
f i l e n a m e = E : \ Education \ U n i v e r s i t y \MS\4 th S e m e s t e r \ T h e s i s \ V e r s i o n s \Qt\
v1 . 6 \ b u i l d DCRDesktop_Qt_5_6_0_MSVC2015_64bitDebug\ P r o f i l e s \
P r o f i l e D a t a . tpd ;
3 delimiterIn = \t ;
headerlinesIn = 1;
5 P r o f i l e = importdata ( filename , d e l i m i t e r I n , h e a d e r l i n e s I n ) ;
7 %S t o r e x , y , z c o m b i n a t i o n on x , y and z v e c t o r s
x=P r o f i l e . data ( : , 2 ) ;
9 y=P r o f i l e . data ( : , 1 ) ;
z=P r o f i l e . data ( : , 3 ) ;
11
p l o t 3 ( x , y , z , . )
13
t r i = de l a u na y ( x , y ) ;
15 plot (x , y , . )
43
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
17 [ r , c ] = size ( tri ) ;
disp ( r )
19
h = trisurf ( tri , x , y , z) ;
21 axis vis3d
axis off
23 l = l i g h t ( P o s i t i o n ,[ 50 15 2 9 ] ) ;
s e t ( gca , CameraPosition , [ 2 0 8 50 7 6 8 7 ] ) ;
25 l i g h t i n g phong
shading i n t e r p
27 c o l o r b a r EastOutside
Listing 6.1. Data file loading
As previously mentioned, in order to run this program again and again for different
newly scanned samples, file name points to "ProfileData.tpd". The ".tpd" extension
has been chosen to the courtesy of Tire Profiles company and stands for Tire Pro-
files Data. According to the previous convention about filling data file, it has one
row of column headers and values are separated by means of tabs. The code for
representing x,y and z vectors in 3D format, uses point by point drawing and then
changing the color based on corresponding z value. Figure 6.1 shows output of these
commands, As it is possible to observe the DOT code on tire is "DOT CN3R PY42".
On the right side of this figure, there is a bar showing corresponding color for
different distances. These distances are actually the distances between each point
and laser sensor. For example on right side of tire representation, color dedicated
to characters are less than background color in the sense that the corresponding
distance value is less than the same value for background. Which means the DOT
characters are closer to the laser sensor rather than the background.
Step 2: For further improvements on achieved results it is a good choice to store x,y
and z vectors inside a matrix called P such a way that x and y values are row and
column indices and z values are stored as matrix elements values. Listing 6.2 lists
all required MATLAB commands to transform x,y,z vectors to P matrix.
1 %Loading Measured data t o m atrix P
Yindex =0;
3 Xindex =0;
y v a l u e =1;
5 f o r i =1: l e n g t h ( x )
i f ( y ( i )==y v a l u e )
7 Xindex=Xindex +1;
else
9 Yindex=Yindex +1;
Xindex =1;
11 y v a l u e=y ( i ) ;
end
13 P( Yindex , Xindex )=z ( i ) ;
end
15
44
6 Image Pre-Processing
In this portion of code, one loop sweeps all x,y,z elements and fill P matrix accord-
ingly. Note that the value stored in x vector is not needed and only the sequence of
data is important. After filling P matrix based on x,y,z vectors, it is possible to have
zero elements in P because at time of acquisition sensor couldnt scan for example
400 points of a few lines. In such cases that are usually a result of functional criterion
limits trespassing, it is necessary to fill those zero elements with a neighbor non zero
element. When P matrix is completely built up and does not have zero elements
inside, surf function can make a better 3D surface representation like in figure 6.2.
45
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Step 3: As it is observable from 3D image, the acquisition is not perfect, in the sense that
sensor did not maintain a constant vertical distance to tire during scanning process.
To reduce effect of this matter, listing 6.3 lists a few simple commands to level the
3D model from one side.
f o r x=1: s i z e (P , 1 )
2 P( x , : ) =P( x , : ) (P( x , 1 )P ( 1 : 1 ) ) ;
end
4 P= f l i p l r (P) ;
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n L e v e l e d )
Listing 6.3. Leveled Model
In this code portion, all points of every single horizontal line are modified such a
way that the starting point of all lines have the same value. Figure 6.3 represents
the result of leveling process.
Step 4: Now that the 3D model is leveled, it is the time to scan for abrupt changes in the
model. The only way to recognize and the main reason behind using laser sensor
instead of camera is to find DOT code based on altitude changes instead of trying
to recognize it from a black on black pattern. Listing 6.4 summarizes all required
commands to find abrupt changes.
1 %% F i n d i n g maximum two c o n s e c u t i v e p o i n t s d i f f e r e n c e
46
6 Image Pre-Processing
f o r y=1: s i z e (P , 2 )
3 MaxDeltaVector ( y ) =0;
f o r x=2: s i z e (P , 1 )
5 i f ( abs (P( x , y )P( x 1,y ) )>MaxDeltaVector ( y ) )
MaxDeltaVector ( y )=abs (P( x , y )P( x 1,y ) ) ;
7 end
end
9 end
MaxDelta=max( MaxDeltaVector ) ;
11
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( r i g h t t o l e f t
)
13 f o r y=1: s i z e (P , 2 )
P1 ( 1 , y )=min (P ( : ) ) ;
15 P1 ( 2 , y )=min (P ( : ) ) ;
f o r x=3: s i z e (P , 1 )
17 ExpectedValue=2P( x 1,y )P( x 2,y ) ;
i f ( abs (P( x , y )ExpectedValue ) <0.3 MaxDelta )
19 P1 ( x , y )=min (P ( : ) ) ;
else
21 P1 ( x , y )=P( x , y ) ;
end
23 end
end
25
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( l e f t t o r i g h t
)
27 f o r y=1: s i z e (P , 2 )
47
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
P1 ( end , y )=min (P ( : ) ) ;
29 P1 ( end 1 ,y )=min (P ( : ) ) ;
f o r x=s i z e (P , 1 ) 2: 1:1
31 ExpectedValue=2P( x+1 ,y )P( x+2 ,y ) ;
i f ( abs (P( x , y )ExpectedValue ) >0.3 MaxDelta && P1 ( x , y )==0)
33 P1 ( x , y )=P( x , y ) ;
end
35 end
end
37 f i g u r e , s u r f ( P1 ) , t i t l e ( Abrupt a l t i t u d e c h a n g e s i n 3D model )
Listing 6.4. Procedure to Find Abrupt Altitude Changes
This step works by finding the most variation between two consecutive points. This
value gives an order of expected variation. Its expected to have the most variations
in altitude where ever there is an edge of DOT code. At the rest of code, MATLAB
will try to find points that have a absolute consecutive change more than 0.3 times
of maximum abrupt changes. These points will be considered as potential edges.
This control process is executed twice, one from right to left and one from left to
right. All potentially important points are gathered in P1 matrix. Figre 6.4 shows
abrupt changes in 3D model, all other points have been changed to have altitude
equal to zero.
Step 5: As its observable from previous step result, the algorithm has found only the
edges as it was intended to do. In order to have characters also included in the
segmented area, listing 6.5 contains the appropriate code to add a point to selected
48
6 Image Pre-Processing
points if there is an already selected point in its neighborhood with size of three
points.
1 % Adding n e i g h b o r p o i n t s t o c o l l e c t e d data
N e i g h b o r S i z e =3;
3 P2=P1 ;
f o r y=1+N e i g h b o r S i z e : s i z e (P , 2 )N e i g h b o r S i z e
5 f o r x=1+N e i g h b o r S i z e : s i z e (P , 1 )N e i g h b o r S i z e
f o r i=N e i g h b o r S i z e : N e i g h b o r S i z e
7 f o r j=N e i g h b o r S i z e : N e i g h b o r S i z e
i f ( P1 ( x+i , y+j )==P( x+i , y+j ) )
9 P2 ( x , y )=P( x , y ) ;
end
11 end
end
13 end
end
15 f i g u r e , s u r f ( P2 ) , t i t l e ( Added n e i g h b o u r s )
Listing 6.5. Adding Neighbors to Selected Points
This code uses four nested loops to check if a point has to be added to selected points
or not. In order to prevent from selecting all points, a new P2 matrix is filled based
on P1 matrix data.
Step 6: For image segmentation it is better to have the 3D model with miinmum value
equal to zero. In this simple step minimum value of matrix is decremented from all
49
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
points. Note that the minimum value is referred to the minimum value of all points
without considering points with zero value. Listing 6.6 lists these simple commands.
1 % Remove min v a l u e ( e x c e p t 0 )
P2=P2min ( P2 ( : ) ) ;
3 minvalue=i n f ;
f o r y=1: s i z e (P , 2 )
5 f o r x=1: s i z e (P , 1 )
i f ( P2 ( x , y ) ~=0 && P2 ( x , y )<minvalue )
7 minvalue=P2 ( x , y ) ;
end
9 end
end
11 f o r y=1: s i z e (P , 2 )
f o r x=1: s i z e (P , 1 )
13 i f ( P2 ( x , y ) ~=0)
P2 ( x , y )=P2 ( x , y )minvalue ;
15 end
end
17 end
f i g u r e , s u r f ( P2 ) , t i t l e ( Min Value Removed )
19 P=P2 ;
Listing 6.6. Removing Minimum Value (Except 0)
Figure 6.6 depicts the new 3D model which has zero minimum value. Comparison
may be made by considering the z axis numbers.
50
6 Image Pre-Processing
Step 7: Now that the 3D manipulation is made effectively by exploiting distance mea-
surement feature, it is possible to convert this 3D model to a normal 2D image to
perform some simple image pre-processing techniques. Listing 6.7 denotes required
commands to perform this important step.
1 % Image Segmentation
P=P ;
3 I = mat2gray (P) ;
mask = f a l s e ( s i z e ( I ) ) ;
5
f o r x=1: s i z e ( I , 1 )
7 f o r y=1: s i z e ( I , 2 )
i f (P( x , y ) >=0.9max(P ( : ) ) )
9 mask ( x , y )=t r u e ;
end
11 end
end
13
W = g r a y d i f f w e i g h t ( I , mask , G r a y D i f f e r e n c e C u t o f f , 2 5 ) ;
15 thresh = 0.01;
[BW, D] = imsegfmm (W, mask , t h r e s h ) ;
17 figure
imshow (BW)
19 t i t l e ( Segmented BW Image )
This step primarily uses a "mat2gray" function to just scale each matrix element value
to have a number between 0 and 255. "mask" variable is used to define a mask which
represents potential seeds of image segmentation. This binary matrix is filled with
ones for points with highest values (above 90%) and zeros for all remaining points.
"graydiffweight" uses the grayscale image and provided mask to calculate a weight
for pixels according to the difference between their value and masked point values.
At the end, "imgsegfmm" function performs segmentation based on the weighted
values, provided mask and a threshold which determines the border of black and
white. Figure 6.7 shows the result of this process.
Step 8: It seems that the code has selected the correct region that contains the DOT
code but with current black and white image it is not possible to perform OCR for
sure. So in this step, segmentation mask created by previous step is used to filter
original grayscale image obtained by beginning of previous step.
1 f o r x=1: s i z e ( I , 1 )
f o r y=1: s i z e ( I , 2 )
3 i f (BW( x , y )==f a l s e )
P( x , y ) =0;
5 end
end
7 end
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( Segmented G r a y s c a l e Image )
51
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
This code uses BW image created by previous step to filter original P matrix. Figure
6.8 reveals grayscale segmented image which is quite promising.
Step 9: This image can be improved by means of contrast stretching. Listing 6.9 denotes
required commands one after the other.
%C o n t r a s t S t r e t c h i n g
2 P=Pmin (P(P>0) ) ;
P(P<0)=0;
4 P=P . 255/max(P ( : ) ) ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( C o n t r a s t S t r e t c h e d Image ) ;
52
6 Image Pre-Processing
This code guarantees to have minimum and maximum grayscale values by removing
minimum value and then stretch the gray value spectrum to 255. Figure 6.9 shows
improved constrast stretched image.
Step 10: Since most of OCR techniques works best when the input image has black text
on white background, 6.10 denotes the simple method to find the negative image.
1 %Negate Image
P=255P ;
3 I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( N e g a t i v e Image ) ;
Listing 6.10. Negative Image
Finally, figure 6.10 shows the result of 10 consecutive steps for image pre-processing.
53
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Although this image pre-processing is not perfect but it offers a good approach to make the
3D model clearer for image processing and specifically OCR. Anyway the thesis goal was
mainly to achieve a stable working condition for laser sensor communication and scanner
software acquisition.
In this case there is no advantage to use slots over class functions because the processed
data by the profile processor object should be handled differently than just connecting
it to a user interface element slot. But for signals part, listing 6.12 shows two signals
declared by this class.
1 signals :
v o i d SendImage ( QPixmap Image ) ;
3 v o i d Sen dCurr entOp erati on ( QString Command) ;
Listing 6.12. ProfileProcessor Signals
54
6 Image Pre-Processing
1 v o i d P r o f i l e P r o c e s s o r : : P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation )
{
3 QFile C o n f i g u r a t i o n ;
Configuration . setFileName ( C o n f i g u r a t i o n F i l e L o c a t i o n ) ;
5 C o n f i g u r a t i o n . open ( QIODevice : : ReadOnly ) ;
QTextStream C o n f i g u r a t i o n S t r e a m ;
7 C o n f i g u r a t i o n S t r e a m . s e t D e v i c e (& C o n f i g u r a t i o n ) ;
w h i l e ( ! C o n f i g u r a t i o n S t r e a m . atEnd ( ) )
9 {
QString A cti on=C o n f i g u r a t i o n S t r e a m . r e a d L i n e ( ) ;
11 i f ( Acti on . c o n t a i n s ( " Load F i l e " ) )
{
13 LoadProfile ( ProfileDataLocation ) ;
}
15 e l s e i f ( Act ion . c o n t a i n s ( " C o r r e c t O r i e n t a t i o n " ) )
{
17 CorrectOrientation () ;
}
19 e l s e i f ( Act ion . c o n t a i n s ( " I n v e r t C o l o r " ) )
{
21 InvertColor () ;
}
23 e l s e i f ( Act ion . c o n t a i n s ( " Sharpen Edges " ) )
{
25 SharpenEdges ( ) ;
}
27 }
29 Configuration . close () ;
ProfileMat . r e l e a s e () ;
31 ProfileData . close () ;
33 }
Listing 6.13. ProfileProcessor Process Function
This portion of code, defines that this function requires two arguments as inputs. One
is the location address of a profile data file and the other is the location address of a
configuration file. Profile data file is the same file that has been used to store acquisition
data while configuration file is a new input file which dictates to processor how to process
files. This new file may seems to make the system unnecessarily complex but this option is
intended to make it simpler. Sometimes when a utility software similar to this one is sold,
it happens that the system is no longer be able to perform its job. In most cases when
a technical support gets dispatched and checks the system, it comes up that the system
needs to reconfigure to adopt to the new situation. A change in situation may be caused
by even different illumination. So in this cases it is much easier to change a configuration
file instead of whole program. By the way, this function reads contents of configuration
file and decides what is the next action to take. After all actions are finished, it closes two
text files.
Now lets analyze four actions that have been already implemented.
LoadProfile
55
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
Listing 6.14 lists the required functions to load a profile data file.
1 v o i d P r o f i l e P r o c e s s o r : : L o a d P r o f i l e ( QString F i l e L o c a t i o n )
{
3 P r o f i l e D a t a . setFileName ( F i l e L o c a t i o n ) ;
P r o f i l e D a t a . open ( QIODevice : : ReadOnly ) ;
5 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
i n t x , y , z , y o l d =0 , x i n d e x =1, y i n d e x =1;
7 i n t xindexmax =0 , yindexmax =0 ,zmax=0, zmin=s t d : : n u m e r i c _ l i m i t s <i n t > : :
max ( ) ;
QString ReadLine ;
9 QList <QString> S p l i t t e d D a t a ;
11 // Scan f i l e i n o r d e r t o f i n d t h e image d i m e n s i o n s
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
13 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
15 {
ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
17 S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
19 x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
21 i f ( y!= y o l d )
{
23 y i n d e x++;
x i n d e x =1;
25 y o l d=y ;
}
27 x i n d e x++;
i f ( xindex>xindexmax ) xindexmax=x i n d e x ;
29 i f ( y>yindexmax ) yindexmax=y ;
i f ( z>zmax ) zmax=z ;
31 i f ( z<zmin ) zmin=z ;
}
33
// C r e a t e Mat o b j e c t based on image s i z e
35 P r o f i l e M a t= Mat : : z e r o s ( yindexmax +1 , xindexmax +1 ,CV_8UC1) ;
37 // Read f i l e a g a i n t o f i l l t h e Mat o b j e c t a c c o r d i n g l y
ProfileStream . seek (0) ;
39 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
41 x i n d e x =1;
y i n d e x =1;
43 w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
{
45 ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
47 y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
49 z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
i f ( y!= y o l d )
51 {
y i n d e x++;
56
6 Image Pre-Processing
53 x i n d e x =1;
y o l d=y ;
55 }
x i n d e x++;
57 i n t S c a l e d V a l u e =(( zzmin ) 2 5 4 / ( zmaxzmin ) ) +1;
P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= S c a l e d V a l u e ;
59 }
// Check i f i t has z e r o v a l u e s
61 f o r ( y i n d e x =1; yindex<P r o f i l e M a t . rows ; y i n d e x++)
f o r ( x i n d e x =0; xindex<P r o f i l e M a t . c o l s ; x i n d e x++)
63 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
65 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<
uchar >( yindex 1 , x i n d e x ) ;
}
67 f o r ( y i n d e x=P r o f i l e M a t . rows 2; yindex >=0; yindex )
f o r ( x i n d e x=P r o f i l e M a t . c o l s 1; xindex >=0; xindex )
69 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
71 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<
uchar >( y i n d e x +1, x i n d e x ) ;
}
73 emit Se ndCur rentO perat ion ( " P r o f i l e Data Loaded " ) ;
ShowImage ( ) ;
75 }
Listing 6.14. ProfileProcessor Load Profile
The LoadProfile function primarily opens the data file and reads it line by line.
Two first lines are not important since they are dedicated to column headers. Then
it reads following lines and use the same method of MATLAB program to find
dimensions of P matrix. Open-CV uses a variable of type mat to store and work
with images. This variable dynamically allocates memory and release it when it is
not needed anymore. Copying mat objects by using a=b syntax does not copy the
data but it only copies the pointer. There is a specific function to copy also the
content of mat objects. in the first loop the function scans the file just to find the
appropriate dimensions of final mat object. After that at line 35, it creates a mat
object which is a matrix of appropriate dimensions and defines that the value of
this matrix elements is a single scalar and can be represented by 8 bits. This is the
method that Open-CV deals with grayscale images. Now that the matrix is created
and filled with zeros, its the time to restart reading data file and fill the mat object
accordingly. Same as MATLAB code it is possible to have zero elements inside the
matrix because sensor does not return same number of points for every acquisition,
so it is necessary to fill the zero elements with a neighbors value. Figure 6.11 depicts
the output of this stage.
57
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
1 void P r o f i l e P r o c e s s o r : : CorrectOrientation ( )
{
3 // Check i f i t i s n e c e s s a r y t o r o t a t e t h e image
i f ( P r o f i l e M a t . c o l s <P r o f i l e M a t . rows )
5 transpose ( ProfileMat , ProfileMat ) ;
emit Se ndCur rentO perat ion ( " O r i e n t a t i o n C o r r e c t e d " ) ;
7 ShowImage ( ) ;
}
Listing 6.15. ProfileProcessor Correct Orientation
This function and all others send the title of operation and also the image to "Main-
Window" by means of two signals. Figure 6.12 depicts the image with corrected
orientation.
Same as MATLABs procedure, next step is to invert colors. Listing 6.16 shows the
usage of "bitwise_not" command that is defined in Open-CV library.
void P r o f i l e P r o c e s s o r : : InvertColor ( )
2 {
bitwise_not ( ProfileMat , ProfileMat ) ;
4 emit Se ndCur rentO perat ion ( " C o l o r s I n v e r t e d " ) ;
ShowImage ( ) ;
6 }
Listing 6.16. ProfileProcessor Invert Colors
58
6 Image Pre-Processing
Sharpen edges action is a bit different from what was done in MATLAB procedure.
Listing 6.17 shows the steps of this action.
v o i d P r o f i l e P r o c e s s o r : : SharpenEdges ( )
2 {
4 G a u s s i a n B l u r ( P r o f i l e M a t , ProfileMatAux , S i z e ( 0 , 0 ) , 3 ) ;
addWeighted ( P r o f i l e M a t , 1 . 5 , ProfileMatAux , 0.5 , 0 , ProfileMatAux )
;
59
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
6 P r o f i l e M a t=ProfileMatAux ;
emit Se ndCur rentO perat ion ( " Edges Sharpened " ) ;
8 ShowImage ( ) ;
}
Listing 6.17. ProfileProcessor Sharpen Edges
This function finds a new image by applying Gaussian blur technique. Then this
blurred new image is deducted from original one with a half weight. The resulting
image is depicted on figure 6.14.
As previously mentioned all of these functions use a function to send the image
result. Listing 6.18 denotes the required commands to transform a mat object to a
QPixmap object so that Qt will be able to show it as a background image of a label.
1 v o i d P r o f i l e P r o c e s s o r : : ShowImage ( )
{
3 QThread : : msleep ( 2 0 0 ) ;
s t a t i c QVector<QRgb> s C o l o r T a b l e ;
5
// o n l y c r e a t e our c o l o r t a b l e once
7 i f ( s C o l o r T a b l e . isEmpty ( ) )
{
9 f o r ( i n t i = 0 ; i < 2 5 6 ; ++i )
s C o l o r T a b l e . push_back ( qRgb ( i , i , i ) ) ;
11 }
60
6 Image Pre-Processing
15
QPixmap ImageQPixmap = QPixmap : : fromImage ( ImageQImage ) ;
17 emit SendImage ( ImageQPixmap ) ;
}
Listing 6.18. ProfileProcessor ShowImage
ShowImage function creates a color table only once to map a single color value to
three values colors. This action is necessary since QImage objects needs to store
color data in RGB format. When the QImage object is created, it can be converted
to QPixmap object and sent to MainWindow.
These actions were the implemented ones in this thesis. Since the main focus of it
was on design and build of RS485 interface, other image processing actions were left for
future studies. The most important point is that this software created an infrastructure
for further completions which is easy to understand and interact.
61
62
Chapter 7
Conclusion
This thesis analyzed the importance of DOT code and created a device to make possible
the communication between a laser sensor and PC. It also developed different computer
programs to acquire and process data. In order to have the final device to be sold there
are still following works to be done.
A cloud server should be procured and the corresponding program should be up-
loaded on it.
A wireless module should be added to system such a way that it interacts with
micro-controller and MAX485 on behalf of USB to Serial converter.
Further actions should be added to Qt plus Open-CV application. The substrate for
this addition has been already done. So this work will be fast.
A PC application should be developed to just receive the final answer of cloud which
is a DOT code and print it with its corresponding data on a paper. This application
needs socket programming.
Although this approach can be modified to have better and more accurate data, the
variable illumination (structured lighting) method will be much more accurate since in
this approach there is no need to move the device over tire and it can be done by hovering
the device on DOT code for less than a second.
63
64
Bibliography
65
Appendices
66
Appendix A
Micro-controller C Code
#i n c l u d e <mega16 . h>
2 #i n c l u d e <d e l a y . h>
// D e c l a r e your g l o b a l v a r i a b l e s h e r e
4 int i ;
#d e f i n e DATA_REGISTER_EMPTY (1<<UDRE)
6 #d e f i n e RX_COMPLETE (1<<RXC)
#d e f i n e FRAMING_ERROR (1<<FE)
8 #d e f i n e PARITY_ERROR (1<<UPE)
#d e f i n e DATA_OVERRUN (1<<DOR)
10
// Get a c h a r a c t e r from t h e USART R e c e i v e r
12 #i f n d e f _DEBUG_TERMINAL_IO_
#d e f i n e _ALTERNATE_GETCHAR_
14 #pragma used+
char getchar ( void )
16 {
c h a r s t a t u s , data ;
18 while (1)
{
20 w h i l e ( ( ( s t a t u s=UCSRA) & RX_COMPLETE)==0) ;
data=UDR;
22 i f ( ( s t a t u s & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN) )==0)
r e t u r n data ;
24 }
}
26 #pragma used
#e n d i f
28
// Write a c h a r a c t e r t o t h e USART T r a n s m i t t e r
30 #i f n d e f _DEBUG_TERMINAL_IO_
#d e f i n e _ALTERNATE_PUTCHAR_
32 #pragma used+
void putchar ( char c )
34 {
w h i l e ( (UCSRA & DATA_REGISTER_EMPTY)==0) ;
36 UDR=c ;
}
38 #pragma used
67
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
#e n d i f
40
// Standard Input / Output f u n c t i o n s
42 #i n c l u d e <s t d i o . h>
44 v o i d main ( v o i d )
{
46 // D e c l a r e your l o c a l v a r i a b l e s h e r e
c h a r ch , cr , cn ;
48
// I np u t / Output P o r t s i n i t i a l i z a t i o n
50 // Port A i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
52 DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) |
(0<<DDA1) | (0<<DDA0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
54 PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) |
(0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0) ;
56 // Port B i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
58 DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) |
(0<<DDB1) | (0<<DDB0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
60 PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) |
(0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0) ;
62 // Port C i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=In B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=In
64 DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) |
(0<<DDC1) | (0<<DDC0) ;
// S t a t e : B i t 7=T B i t 6=T B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
66 PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) |
(0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0) ;
68 // Port D i n i t i a l i z a t i o n
// Fu nction : B i t 7=In B i t 6=Out B i t 5=In B i t 4=In B i t 3=In B i t 2=In B i t 1=In B i t 0=
In
70 DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) |
(0<<DDD1) | (0<<DDD0) ;
// S t a t e : B i t 7=T B i t 6=0 B i t 5=T B i t 4=T B i t 3=T B i t 2=T B i t 1=T B i t 0=T
72 PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) |
(0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0) ;
74 // Timer / Counter 0 i n i t i a l i z a t i o n
// Clock s o u r c e : System Clock
76 // Clock v a l u e : Timer 0 Stopped
// Mode : Normal top=0xFF
78 // OC0 output : D i s c o n n e c t e d
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02 ) | (0<<
CS01 ) | (0<<CS00 ) ;
80 TCNT0=0x00 ;
OCR0=0x00 ;
82
68
A Micro-controller C Code
// Timer / Counter 1 i n i t i a l i z a t i o n
84 // Clock s o u r c e : System Clock
// Clock v a l u e : Timer1 Stopped
86 // Mode : Normal top=0xFFFF
// OC1A output : D i s c o n n e c t e d
88 // OC1B output : D i s c o n n e c t e d
// N o i s e C a n c e l e r : O f f
90 // I np u t Capture on F a l l i n g Edge
// Timer1 Overflow I n t e r r u p t : O f f
92 // I np u t Capture I n t e r r u p t : O f f
// Compare A Match I n t e r r u p t : O f f
94 // Compare B Match I n t e r r u p t : O f f
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) |
(0<<WGM10) ;
96 TCCR1B=(0<<ICNC1) | (0<<ICES1 ) | (0<<WGM13) | (0<<WGM12) | (0<<CS12 ) | (0<<
CS11 ) | (0<<CS10 ) ;
TCNT1H=0x00 ;
98 TCNT1L=0x00 ;
ICR1H=0x00 ;
100 ICR1L=0x00 ;
OCR1AH=0x00 ;
102 OCR1AL=0x00 ;
OCR1BH=0x00 ;
104 OCR1BL=0x00 ;
126 // USART i n i t i a l i z a t i o n
// Communication Parameters : 8 Data , 1 Stop , Even P a r i t y
128 // USART R e c e i v e r : On
// USART T r a n s m i t t e r : On
130 // USART Mode : Asynchronous
// USART Baud Rate : 57600
69
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
70
A Micro-controller C Code
180 PORTD. 6 = 1 ;
p u t c h a r ( ch ) ;
182 }
else i f ( ch==0x0B )
184 {
// p u t c h a r ( ch ) ;
186 f o r ( i =0; i <100; i ++) ;
PORTD. 6 = 0 ;
188 }
else
190 p u t c h a r ( ch ) ;
}
192 }
71
Appendix B
#i f n d e f LASERSENSOR_H
2 #d e f i n e LASERSENSOR_H
4 #i n c l u d e <Q t S e r i a l P o r t >
#i n c l u d e <QString>
6
c l a s s L a s e r S e n s o r : p u b l i c QObject
8 {
Q_OBJECT
10
12 public :
L a s e r S e n s o r ( ) ; // C o n s t r u c t o r
14 ~LaserSensor () ;
16 private slots :
void ReadProfile ( ) ;
18 v o i d F i n d A v a i l a b l e P o r t s ( ) ; // S e a r c h e s f o r a l l a v a i l a b l e COM p o r t s
v o i d I n i t C o n n e c t i o n ( QString PORTName) ; // I n i t i a t e s t h e c o n n e c t i o n
20 v o i d CheckConnection ( ) ; // Checks f o r c o n n e c t i o n p r e s e n c e
v o i d R e a d A p p l i c a t i o n E r r o r ( ) ; // Reads a p p l i c a t i o n e r r o r code
22 v o i d ReadVendorInfo ( ) ;
void ReadDeviceInfo ( ) ;
24 v o i d ReadBusAddress ( ) ;
v o i d WriteBusAddress ( i n t BusAddressValue ) ;
26 v o i d ReadBaudRate ( ) ;
v o i d WriteBaudRate ( i n t S e l e c t ) ;
28 v o i d ReadRS485Lock ( ) ;
v o i d WriteRS485Lock ( b o o l Switch ) ;
30 v o i d ReadTouchButtonLock ( ) ;
v o i d WriteTouchButtonLock ( b o o l Switch ) ;
32 v o i d ReadMeasurementType ( ) ;
v o i d WriteMeasurementType ( i n t S e l e c t ) ;
34 v o i d ReadMeasurementValue ( ) ;
v o i d ReadAllMeasurementValues ( ) ;
36 v o i d ReadFieldOfView ( ) ;
v o i d WriteFieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
38 v o i d WriteFiledOfViewToMax ( ) ;
72
B Laser Sensor Header Code
void ReadObjectType ( ) ;
40 void WriteObjectType ( b o o l Switch ) ;
void ReadPrecision () ;
42 void WritePrecision ( int Select ) ;
void ReadLaserOffDataHold ( ) ;
44 void WriteLaserOffDataHold ( b o o l Switch ) ;
void ReadFlexMountEnable ( ) ;
46 void WriteFlexMountEnable ( b o o l Switch ) ;
void ReadSetFlexMount ( ) ;
48 void WriteSetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
void WriteTeachFlexMountCommand ( f l o a t R e f e r e n c e T h i c k n e s s ) ;
50 void ReadDiagnoseMode ( ) ;
void WriteDiagnoseMode ( b o o l Switch ) ;
52 void WriteStoreConfigurationCommand ( i n t C o n f i g ) ;
void WriteResetToFactorySettingsCommand ( i n t Command) ;
54 void SampleNoChanged ( QString SampleNumber ) ;
void CloseConnection ( ) ;
56
signals :
58 void A v a i l a b l e P o r t s ( i n t TotalNumber , QVector<QString> P o r t s ) ; // S e a r c h e s
for a l l a v a i l a b l e COM p o r t s
void ConnectionStatus ( bool Status ) ;
60 void A p p l i c a t i o n E r r o r ( i n t A p p l i c a t i o n E r r o r ) ; // Reads a p p l i c a t i o n e r r o r
code
void VendorID ( i n t Vendor_ID ) ;
62 void VendorName ( QString Vendor_Name ) ;
void DeviceID ( i n t Device_ID ) ;
64 void VariantID ( i n t Variant_ID ) ;
void SensorType ( QString Sensor_Type ) ;
66 void SerialNumber ( QString Serial_Number ) ;
void BusAddress ( i n t BusAddressValue ) ;
68 void BaudRate ( i n t BuadRateValue ) ;
void RS485Lock ( b o o l Switch ) ;
70 void TouchButtonLock ( b o o l Switch ) ;
void MeasurementType ( QString Type ) ;
72 void MeasurementValue ( f l o a t MeasurementValue , QString Q u a l i t y ) ;
void Average ( QString a v e r a g e ) ;
74 void Max ( QString max) ;
void Min ( QString min ) ;
76 void D e l t a ( QString d e l t a ) ;
void S t a n d a r d D e v i a t i o n ( QString s t a n d a r d d e v i a t i o n ) ;
78 void Q u a l i t y ( QString q u a l i t y ) ;
void FieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t ) ;
80 void ObjectType ( QString ObjectType ) ;
void P r e c i s i o n ( QString P r e c i s i o n ) ;
82 void LaserOffDataHold ( b o o l Switch ) ;
void FlexMountEnable ( b o o l Switch ) ;
84 void SetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e ) ;
void DiagnoseModeEnabled ( ) ;
86 void P r o f i l e ( i n t Xpos [ 3 0 0 ] , i n t Zpos [ 3 0 0 ] ) ;
void SensorTimedOut ( b o o l Switch ) ;
88 void ProfileReady () ;
90 private :
73
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
bool ReceiveResponse ( ) ;
92 v o i d SendCommand ( QString Command) ;
QString CRCMake( QString Command) ;
94 QSerialPort s e r i a l ;
i n t DeviceAddress ;
96 QString Response ;
Q S t r i n g L i s t Payloads ;
98 QFile P r o f i l e D a t a ;
QTextStream P r o f i l e S t r e a m ;
100 QFile P r o f i l e D a t a 1 ;
QTextStream P r o f i l e S t r e a m 1 ;
102 QString SampleNo ;
i n t Yindex ;
104 bool f i l e c r e a t e d ;
};
106
108 #e n d i f // LASERSENSOR_H
74
Appendix C
#i n c l u d e " l a s e r s e n s o r . h "
2
LaserSensor : : LaserSensor ()
4 {
qRegisterMetaType<QVector<QString> >( " QVector<QString>" ) ;
6 s e r i a l = new Q S e r i a l P o r t ( t h i s ) ;
s e r i a l >setBaudRate ( Q S e r i a l P o r t : : Baud115200 ) ;
8 s e r i a l >s e t D a t a B i t s ( Q S e r i a l P o r t : : Data8 ) ;
s e r i a l >s e t P a r i t y ( Q S e r i a l P o r t : : EvenParity ) ;
10 s e r i a l >s e t S t o p B i t s ( Q S e r i a l P o r t : : OneStop ) ;
s e r i a l >s e t F l o w C o n t r o l ( Q S e r i a l P o r t : : NoFlowControl ) ;
12 D e v i c e A d d r e s s =1;
Yindex =0;
14 f i l e c r e a t e d=f a l s e ;
SampleNo=" 1 " ;
16 }
75
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
else
40 {
emit C o n n e c t i o n S t a t u s ( f a l s e ) ;
42 }
SendCommand ( "W010 ; 0 " ) ;
44 ReceiveResponse ( ) ;
}
46
v o i d L a s e r S e n s o r : : CheckConnection ( )
48 {
50 }
66 }
80 v o i d L a s e r S e n s o r : : ReadBusAddress ( )
{
82
}
84
v o i d L a s e r S e n s o r : : WriteBusAddress ( i n t BusAddressValue )
86 {
88 }
90 v o i d L a s e r S e n s o r : : ReadBaudRate ( )
{
92
76
C Laser Sensor C++ Code
}
94
v o i d L a s e r S e n s o r : : WriteBaudRate ( i n t S e l e c t )
96 {
98 }
100 v o i d L a s e r S e n s o r : : ReadRS485Lock ( )
{
102
}
104
v o i d L a s e r S e n s o r : : WriteRS485Lock ( b o o l Switch )
106 {
108 }
110 v o i d L a s e r S e n s o r : : ReadTouchButtonLock ( )
{
112
}
114
v o i d L a s e r S e n s o r : : WriteTouchButtonLock ( b o o l Switch )
116 {
118 }
120 v o i d L a s e r S e n s o r : : ReadMeasurementType ( )
{
122
}
124
v o i d L a s e r S e n s o r : : WriteMeasurementType ( i n t S e l e c t )
126 {
128 }
130 v o i d L a s e r S e n s o r : : ReadMeasurementValue ( )
{
132
}
134
v o i d L a s e r S e n s o r : : ReadAllMeasurementValues ( )
136 {
SendCommand ( " R022 " ) ;
138 i f ( ReceiveResponse ( ) )
{
140 emit Average ( Payloads [ 1 ] ) ;
emit Max( Payloads [ 2 ] ) ;
142 emit Min ( Payloads [ 3 ] ) ;
emit D e l t a ( Payloads [ 4 ] ) ;
144 emit S t a n d a r d D e v i a t i o n ( Payloads [ 5 ] ) ;
emit Q u a l i t y ( Payloads [ 6 ] ) ;
146 }
77
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
}
148
v o i d L a s e r S e n s o r : : ReadFieldOfView ( )
150 {
152 }
154 v o i d L a s e r S e n s o r : : WriteFieldOfView ( i n t L i m i t L e f t , i n t L i m i t R i g h t )
{
156
}
158
v o i d L a s e r S e n s o r : : WriteFiledOfViewToMax ( )
160 {
162 }
164 v o i d L a s e r S e n s o r : : ReadObjectType ( )
{
166
}
168
v o i d L a s e r S e n s o r : : WriteObjectType ( b o o l Switch )
170 {
172 }
182 }
184 v o i d L a s e r S e n s o r : : ReadLaserOffDataHold ( )
{
186
}
188
v o i d L a s e r S e n s o r : : WriteLaserOffDataHold ( b o o l Switch )
190 {
192 }
194 v o i d L a s e r S e n s o r : : ReadFlexMountEnable ( )
{
196
}
198
v o i d L a s e r S e n s o r : : WriteFlexMountEnable ( b o o l Switch )
200 {
78
C Laser Sensor C++ Code
202 }
204 v o i d L a s e r S e n s o r : : ReadSetFlexMount ( )
{
206
}
208
v o i d L a s e r S e n s o r : : WriteSetFlexMount ( f l o a t Angle , f l o a t D i s t a n c e )
210 {
212 }
214 v o i d L a s e r S e n s o r : : WriteTeachFlexMountCommand ( f l o a t R e f e r e n c e T h i c k n e s s )
{
216
}
218
v o i d L a s e r S e n s o r : : ReadDiagnoseMode ( )
220 {
222 }
79
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
252 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
P r o f i l e S t r e a m << "Y\tX\ t \Z " <<e n d l <<e n d l ;
254 P r o f i l e S t r e a m 1 . s e t D e v i c e (& P r o f i l e D a t a 1 ) ;
P r o f i l e S t r e a m 1 << "Y\tX\ t \Z " <<e n d l <<e n d l ;
256 f i l e c r e a t e d=t r u e ;
}
258 SendCommand ( " R052 " ) ;
i f ( ReceiveResponse ( ) )
260 {
i f ( Payloads [ 0 ] . c o n t a i n s ( "A" ) )
262 {
Q S t r i n g L i s t XZMeasurements ;
264 XZMeasurements=Payloads [ 2 ] . s p l i t ( " " ) ;
i n t TotalMeasurements=XZMeasurements [ 0 ] . t o I n t ( ) ;
266 XZMeasurements . r e m o v e F i r s t ( ) ;
Yindex++;
268 f o r ( i n t i =0; i <TotalMeasurements / 2 ; i ++)
{
270 P r o f i l e S t r e a m << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t "
<<XZMeasurements [ 2 i +1] <<e n d l ;
P r o f i l e S t r e a m 1 << Yindex <<" \ t " << XZMeasurements [ 2 i ] <<" \ t
" <<XZMeasurements [ 2 i +1] <<e n d l ;
272 }
emit P r o f i l e R e a d y ( ) ;
274 }
else
276 {
qDebug ( )<<" E r r o r Handling "<<Payloads [ 0 ] ;
278 i f ( Payloads [1]== " 7 " )
WriteDiagnoseMode ( t r u e ) ;
280 else
ReadProfile () ;
282 }
}
284 else
emit P r o f i l e R e a d y ( ) ;
286 }
288 v o i d L a s e r S e n s o r : : WriteStoreConfigurationCommand ( i n t C o n f i g )
{
290
}
292
v o i d L a s e r S e n s o r : : WriteResetToFactorySettingsCommand ( i n t Command)
294 {
296 }
80
C Laser Sensor C++ Code
304 }
81
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
82
Appendix D
1 clc
clear
3 close all
11 %S t o r e x , y , z c o m b i n a t i o n on x , y and z v e c t o r s
x=P r o f i l e . data ( : , 2 ) ;
13 y=P r o f i l e . data ( : , 1 ) ;
z=P r o f i l e . data ( : , 3 ) ;
15
p l o t 3 ( x , y , z , . )
17
t r i = d e l a u na y ( x , y ) ;
19 plot (x , y , . )
21 [ r , c ] = size ( tri ) ;
disp ( r )
23
h = trisurf ( tri , x , y , z) ;
25 axis vis3d
axis off
27 l = l i g h t ( P o s i t i o n ,[ 50 15 2 9 ] ) ;
s e t ( gca , CameraPosition , [ 2 0 8 50 7 6 8 7 ] ) ;
29 l i g h t i n g phong
shading i n t e r p
31 c o l o r b a r EastOutside
83
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
37 f o r i =1: l e n g t h ( x )
i f ( y ( i )==y v a l u e )
39 Xindex=Xindex +1;
else
41 Yindex=Yindex +1;
Xindex =1;
43 y v a l u e=y ( i ) ;
end
45 P( Yindex , Xindex )=z ( i ) ;
end
47
% Removing z e r o e l e m e n t s from P r o f i l e matrix
49 f o r x =1: s i z e (P , 1 )
f o r y=1: s i z e (P , 2 )
51 i f (P( x , y )==0)
P( x , y )=P( x , y1) ;
53 end
end
55 end
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n )
57
59
%%
61 % f o r y =1: s i z e (P , 2 )
% P ( : , y )=P ( : , y )mean (P ( : , y ) )+mean (P ( : ) ) ;
63 % end
f o r x =1: s i z e (P , 1 )
65 P( x , : ) =P( x , : ) (P( x , 1 )P ( 1 : 1 ) ) ;
end
67 P= f l i p l r (P) ;
f i g u r e , s u r f (P) , t i t l e ( 3D S u r f a c e R e p r e s e n t a t i o n L e v e l e d )
69
%%
71
73 %% F i n d i n g maximum two c o n s e c u t i v e p o i n t s d i f f e r e n c e
f o r y =1: s i z e (P , 2 )
75 MaxDeltaVector ( y ) =0;
f o r x=2: s i z e (P , 1 )
77 i f ( abs (P( x , y )P( x 1 ,y ) )>MaxDeltaVector ( y ) )
MaxDeltaVector ( y )=abs (P( x , y )P( x 1,y ) ) ;
79 end
end
81 end
MaxDelta=max( MaxDeltaVector ) ;
83
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( r i g h t t o l e f t )
85 f o r y =1: s i z e (P , 2 )
P1 ( 1 , y )=min (P ( : ) ) ;
87 P1 ( 2 , y )=min (P ( : ) ) ;
f o r x=3: s i z e (P , 1 )
89 ExpectedValue=2P( x 1,y )P( x 2,y ) ;
i f ( abs (P( x , y )ExpectedValue ) <0.3 MaxDelta )
84
D Profile Processer MATLAB Code
91 P1 ( x , y )=min (P ( : ) ) ;
else
93 P1 ( x , y )=P( x , y ) ;
end
95 end
end
97
% F i n d i n g abrupt z change between two c o n s e c t u i v e p o i n t s ( l e f t t o r i g h t )
99 f o r y =1: s i z e (P , 2 )
P1 ( end , y )=min (P ( : ) ) ;
101 P1 ( end 1 ,y )=min (P ( : ) ) ;
f o r x=s i z e (P , 1 ) 2: 1:1
103 ExpectedValue=2P( x+1 ,y )P( x+2 ,y ) ;
i f ( abs (P( x , y )ExpectedValue ) >0.3 MaxDelta && P1 ( x , y )==0)
105 P1 ( x , y )=P( x , y ) ;
end
107 end
end
109 f i g u r e , s u r f ( P1 ) , t i t l e ( Abrupt a l t i t u d e c h a n g e s i n 3D model )
%%
111 % Adding n e i g h b o r p o i n t s t o c o l l e c t e d data
N e i g h b o r S i z e =3;
113 P2=P1 ;
f o r y=1+N e i g h b o r S i z e : s i z e (P , 2 )N e i g h b o r S i z e
115 f o r x=1+N e i g h b o r S i z e : s i z e (P , 1 )N e i g h b o r S i z e
f o r i=N e i g h b o r S i z e : N e i g h b o r S i z e
117 f o r j=N e i g h b o r S i z e : N e i g h b o r S i z e
i f ( P1 ( x+i , y+j )==P( x+i , y+j ) )
119 P2 ( x , y )=P( x , y ) ;
end
121 end
end
123 end
end
125 f i g u r e , s u r f ( P2 ) , t i t l e ( Added n e i g h b o u r s )
%%
127 % Remove min v a l u e ( e x c e p t 0 )
P2=P2min ( P2 ( : ) ) ;
129 minvalue=i n f ;
f o r y =1: s i z e (P , 2 )
131 f o r x=1: s i z e (P , 1 )
i f ( P2 ( x , y ) ~=0 && P2 ( x , y )<minvalue )
133 minvalue=P2 ( x , y ) ;
end
135 end
end
137 f o r y =1: s i z e (P , 2 )
f o r x=1: s i z e (P , 1 )
139 i f ( P2 ( x , y ) ~=0)
P2 ( x , y )=P2 ( x , y )minvalue ;
141 end
end
143 end
f i g u r e , s u r f ( P2 ) , t i t l e ( Min Value Removed )
85
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
145 P=P2 ;
193
195
%
197 I = mat2gray (P) ; f i g u r e , imshow ( I )
86
D Profile Processer MATLAB Code
%C o n t r a s t S t r e t c h i n g
199 P=Pmin (P(P>0) ) ;
P(P<0)=0;
201 P=P . 255/max(P ( : ) ) ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( C o n t r a s t S t r e t c h e d Image ) ;
203
%Negate Image
205 P=255P ;
I = mat2gray (P) ; f i g u r e , imshow ( I ) , t i t l e ( N e g a t i v e Image ) ;
207
% Perform OCR
209 r e s u l t s = ocr ( I ) ;
87
Appendix E
1 #i f n d e f PROFILEPROCESSOR_H
#d e f i n e PROFILEPROCESSOR_H
3
#i n c l u d e <QWidget>
5 #i n c l u d e <opencv2 / c o r e / c o r e . hpp>
#i n c l u d e <opencv2 / h i g h g u i / h i g h g u i . hpp>
7 #i n c l u d e <opencv2 / imgproc / imgproc . hpp>
#i n c l u d e <QString>
9 #i n c l u d e <i o s t r e a m >
#i n c l u d e <QFile>
11 #i n c l u d e <QTextStream>
#i n c l u d e <QDebug>
13 #i n c l u d e <QGenericMatrix>
#i n c l u d e <QPixmap>
15 #i n c l u d e <QThread>
17 u s i n g namespace s t d ;
u s i n g namespace cv ;
19
class ProfileProcessor : p u b l i c QObject
21 {
Q_OBJECT
23
public :
25 ProfileProcessor () ;
v o i d P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation ) ;
27 signals :
v o i d SendImage ( QPixmap Image ) ;
29 v o i d Sen dCurr entOp erati on ( QString Command) ;
private :
31 v o i d L o a d P r o f i l e ( QString F i l e L o c a t i o n ) ;
v o i d ShowImage ( ) ;
33 void CorrectOrientation ( ) ;
void InvertColor ( ) ;
35 v o i d SharpenEdges ( ) ;
Mat P r o f i l e M a t ;
37 Mat ProfileMatAux ;
88
E Profile Processor Header Code
QFile P r o f i l e D a t a ;
39 QTextStream P r o f i l e S t r e a m ;
QList <QList <i n t >> P r o f i l e M a t r i x ;
41 QPixmap P r o f i l e P i x m a p ;
};
43
#e n d i f // PROFILEPROCESSOR_H
89
Appendix F
#i n c l u d e " p r o f i l e p r o c e s s o r . h "
2
ProfileProcessor : : ProfileProcessor ()
4 {
// qRegisterMetaType<QVector<QString> >(" QVector<QString >") ;
6 }
8 v o i d P r o f i l e P r o c e s s o r : : P r o c e s s ( QString P r o f i l e D a t a L o c a t i o n , QString
ConfigurationFileLocation )
{
10 QFile C o n f i g u r a t i o n ;
Configuration . setFileName ( C o n f i g u r a t i o n F i l e L o c a t i o n ) ;
12 C o n f i g u r a t i o n . open ( QIODevice : : ReadOnly ) ;
QTextStream C o n f i g u r a t i o n S t r e a m ;
14 C o n f i g u r a t i o n S t r e a m . s e t D e v i c e (& C o n f i g u r a t i o n ) ;
w h i l e ( ! C o n f i g u r a t i o n S t r e a m . atEnd ( ) )
16 {
QString A cti on=C o n f i g u r a t i o n S t r e a m . r e a d L i n e ( ) ;
18 i f ( Acti on . c o n t a i n s ( " Load F i l e " ) )
{
20 LoadProfile ( ProfileDataLocation ) ;
}
22 e l s e i f ( Act ion . c o n t a i n s ( " C o r r e c t O r i e n t a t i o n " ) )
{
24 CorrectOrientation () ;
}
26 e l s e i f ( Act ion . c o n t a i n s ( " I n v e r t C o l o r " ) )
{
28 InvertColor () ;
}
30 e l s e i f ( Act ion . c o n t a i n s ( " Sharpen Edges " ) )
{
32 SharpenEdges ( ) ;
}
34 }
36 Configuration . close () ;
ProfileMat . r e l e a s e () ;
90
F Profile Processor C++ Code
38 ProfileData . close () ;
40 }
42 v o i d P r o f i l e P r o c e s s o r : : L o a d P r o f i l e ( QString F i l e L o c a t i o n )
{
44 P r o f i l e D a t a . setFileName ( F i l e L o c a t i o n ) ;
P r o f i l e D a t a . open ( QIODevice : : ReadOnly ) ;
46 P r o f i l e S t r e a m . s e t D e v i c e (& P r o f i l e D a t a ) ;
i n t x , y , z , y o l d =0 , x i n d e x =1, y i n d e x =1;
48 i n t xindexmax =0 , yindexmax =0 ,zmax=0, zmin=s t d : : n u m e r i c _ l i m i t s <i n t > : : max ( ) ;
QString ReadLine ;
50 QList <QString> S p l i t t e d D a t a ;
52 // Scan f i l e i n o r d e r t o f i n d t h e image d i m e n s i o n s
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
54 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
56 {
ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
58 S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
60 x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
62 i f ( y!= y o l d )
{
64 y i n d e x++;
x i n d e x =1;
66 y o l d=y ;
}
68 x i n d e x++;
i f ( xindex>xindexmax ) xindexmax=x i n d e x ;
70 i f ( y>yindexmax ) yindexmax=y ;
i f ( z>zmax ) zmax=z ;
72 i f ( z<zmin ) zmin=z ;
}
74
// C r e a t e Mat o b j e c t based on image s i z e
76 P r o f i l e M a t= Mat : : z e r o s ( yindexmax +1 , xindexmax +1 ,CV_8UC1) ;
78 // Read f i l e a g a i n t o f i l l t h e Mat o b j e c t a c c o r d i n g l y
ProfileStream . seek (0) ;
80 P r o f i l e S t r e a m . r e a d L i n e ( ) ; // F i r s t L i n e
P r o f i l e S t r e a m . r e a d L i n e ( ) ; // Second L i n e
82 x i n d e x =1;
y i n d e x =1;
84 w h i l e ( ! P r o f i l e S t r e a m . atEnd ( ) )
{
86 ReadLine=P r o f i l e S t r e a m . r e a d L i n e ( ) ;
S p l i t t e d D a t a=ReadLine . s p l i t ( " \ t " ) ;
88 y=S p l i t t e d D a t a . a t ( 0 ) . t o I n t ( ) ;
x=S p l i t t e d D a t a . a t ( 1 ) . t o I n t ( ) ;
90 z=S p l i t t e d D a t a . a t ( 2 ) . t o I n t ( ) ;
i f ( y!= y o l d )
91
Iman AMIRTAHERI: Design RS485 Interface & DOT Code Scanner Software
92 {
y i n d e x++;
94 x i n d e x =1;
y o l d=y ;
96 }
x i n d e x++;
98 i n t S c a l e d V a l u e =(( zzmin ) 2 5 4 / ( zmaxzmin ) ) +1;
P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= S c a l e d V a l u e ;
100 }
// Check i f i t has z e r o v a l u e s
102 f o r ( y i n d e x =1; yindex<P r o f i l e M a t . rows ; y i n d e x++)
f o r ( x i n d e x =0; xindex<P r o f i l e M a t . c o l s ; x i n d e x++)
104 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
106 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<uchar >(
yindex 1, x i n d e x ) ;
}
108 f o r ( y i n d e x=P r o f i l e M a t . rows 2; yindex >=0; yindex )
f o r ( x i n d e x=P r o f i l e M a t . c o l s 1; xindex >=0; xindex )
110 i f ( P r o f i l e M a t . at<uchar >( yindex , x i n d e x )==0)
{
112 P r o f i l e M a t . at<uchar >( yindex , x i n d e x )= P r o f i l e M a t . at<uchar >(
y i n d e x +1, x i n d e x ) ;
}
114 emit Se ndCur rentO perat ion ( " P r o f i l e Data Loaded " ) ;
ShowImage ( ) ;
116 }
118 v o i d P r o f i l e P r o c e s s o r : : ShowImage ( )
{
120 QThread : : msleep ( 2 0 0 ) ;
s t a t i c QVector<QRgb> s C o l o r T a b l e ;
122
// o n l y c r e a t e our c o l o r t a b l e once
124 i f ( s C o l o r T a b l e . isEmpty ( ) )
{
126 f o r ( i n t i = 0 ; i < 2 5 6 ; ++i )
s C o l o r T a b l e . push_back ( qRgb ( i , i , i ) ) ;
128 }
92
F Profile Processor C++ Code
ShowImage ( ) ;
144 }
154
v o i d P r o f i l e P r o c e s s o r : : SharpenEdges ( )
156 {
158 G a u s s i a n B l u r ( P r o f i l e M a t , ProfileMatAux , S i z e ( 0 , 0 ) , 3 ) ;
addWeighted ( P r o f i l e M a t , 1 . 5 , ProfileMatAux , 0.5 , 0 , ProfileMatAux ) ;
160 P r o f i l e M a t=ProfileMatAux ;
emit Se ndCur rentO perat ion ( " Edges Sharpened " ) ;
162 ShowImage ( ) ;
}
93