-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageProcessor.py
More file actions
99 lines (73 loc) · 3.05 KB
/
ImageProcessor.py
File metadata and controls
99 lines (73 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
__author__ = 'Maikel Hofman'
import numpy as np
import cv2
from multibus import BusServer, BusCore, BusClient
class ImageProcessor():
""" Image processing class
Uses multibus on port 15000 to receive commands.
"""
def __init__(self):
self._bus = BusServer.BusServer(15000)
self.Threshold = 170
self.GaussianSigma = 0.5
def start(self):
""" Starts listening
Returns:
Nothing
"""
self._bus.listen()
while True:
packet = self._bus.getPacket()
self._ProcessPacket(packet)
def _ProcessPacket(self, packet):
""" Process an incoming packet
Parameters:
packet -- instance of Multibus.Packet
Returns:
Nothing
"""
if packet.action == BusCore.PacketType.PROCESSPICTURE:
# First get the coordinates from the picture
coords = self.process(cv2.imread(packet.data["pictureLocation"]))
# Process these coords to get 3D coordinates
elif packet.action == BusCore.PacketType.CALIBRATE:
# Do something
print()
else:
print("Unknown Packet\n")
def process(self, Image):
""" Process image to find the laser line.
Keyword arguments:
Image -- 3 dimensional array of the image
Return:
Array consisting of tuples with a x and a y coordinate of the laserline
"""
imageDimension = Image.shape
# Do an inplace conversion to a float. The standard uint8 cannot be used because it has no room for
# negative numbers.
Image = Image.astype(np.float, copy=False)
# Create an array with zeros that has the same (x, y) size of the picture but only 2 dimensions
zeroArray = np.zeros((imageDimension[0], imageDimension[1], 1))
# Remove the colors green and blue from the image
np.copyto(Image[:, :, 0:2], zeroArray, "safe")
# Create gaussian kernel and apply
gaussianImage = cv2.GaussianBlur(Image, (3, 3), self.GaussianSigma)
# Apply threshold and remove negative numbers
gaussianImage[:, :, 2] -= self.Threshold
gaussianImage[:, :, gaussianImage < 0] = 1.0e-15
Coords = list()
# Run a loop through all the rows and find the maximum. Then use a gaussian approximation to find
# the sup-pixel offset.
# TODO: See if this part can be vectorized, should be faster
# Get image imagePlane
imagePlane = gaussianImage[:, :, 2]
for i in range(0, (imageDimension[0] - 1)):
index = imagePlane[i, :].argmax()
maxValue = imagePlane[i, index]
if maxValue > 1.0e-15:
part1 = np.log(imagePlane[i, index - 1]) - np.log(imagePlane[i, index + 1])
part2 = np.log(imagePlane[i, index - 1]) - 2 * np.log(imagePlane[i, index]) + np.log(
imagePlane[i, index + 1])
delta = 0.5 * (part1 / part2)
Coords.append((i, index + delta))
return Coords