PyOPIA 2.4.7__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {pyopia-2.4.7 → pyopia-2.5.0}/PKG-INFO +1 -1
  2. pyopia-2.5.0/pyopia/__init__.py +1 -0
  3. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/instrument/silcam.py +115 -2
  4. pyopia-2.4.7/pyopia/__init__.py +0 -1
  5. {pyopia-2.4.7 → pyopia-2.5.0}/LICENSE +0 -0
  6. {pyopia-2.4.7 → pyopia-2.5.0}/README.md +0 -0
  7. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/background.py +0 -0
  8. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/classify.py +0 -0
  9. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/cli.py +0 -0
  10. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/exampledata.py +0 -0
  11. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/instrument/__init__.py +0 -0
  12. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/instrument/common.py +0 -0
  13. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/instrument/holo.py +0 -0
  14. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/instrument/uvp.py +0 -0
  15. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/io.py +0 -0
  16. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/pipeline.py +0 -0
  17. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/plotting.py +0 -0
  18. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/process.py +0 -0
  19. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/simulator/__init__.py +0 -0
  20. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/simulator/silcam.py +0 -0
  21. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/statistics.py +0 -0
  22. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/tests/__init__.py +0 -0
  23. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/tests/test_classify.py +0 -0
  24. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/tests/test_notebooks.py +0 -0
  25. {pyopia-2.4.7 → pyopia-2.5.0}/pyopia/tests/test_pipeline.py +0 -0
  26. {pyopia-2.4.7 → pyopia-2.5.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyOPIA
3
- Version: 2.4.7
3
+ Version: 2.5.0
4
4
  Summary: A Python Ocean Particle Image Analysis toolbox.
5
5
  Home-page: https://github.com/sintef/pyopia
6
6
  Keywords: Ocean,Particles,Imaging,Measurement,Size distribution
@@ -0,0 +1 @@
1
+ __version__ = '2.5.0'
@@ -51,6 +51,117 @@ def load_mono8(filename):
51
51
  return img
52
52
 
53
53
 
54
+ def load_bayer_rgb8(filename):
55
+ '''load an RG8 .bsilc file from disc and convert it to RGB image
56
+
57
+ Assumes 8-bit Bayer-RG (Red-Green) image in range 0-255
58
+
59
+ Parameters
60
+ ----------
61
+ filename : string
62
+ filename to load
63
+
64
+ Returns
65
+ -------
66
+ array
67
+ raw image float between 0-1
68
+ '''
69
+ img_bayer = np.load(filename, allow_pickle=False).astype(np.int16)
70
+
71
+ # Check the image dimension
72
+ image_shape = np.shape(img_bayer)
73
+ if len(image_shape) > 2:
74
+ if image_shape[2] == 1:
75
+ img_bayer = img_bayer[:, :, 0]
76
+ else:
77
+ raise RuntimeError('Invalid image dimension')
78
+
79
+ M, N = img_bayer.shape[:2] # Number of pixels in image height and width
80
+ img_bayer_min, img_bayer_max = np.min(img_bayer), np.max(img_bayer)
81
+
82
+ # img is a reconstructed RGB image
83
+ img = np.zeros((M, N, 3), dtype=np.uint8)
84
+ img[0:M:2, 0:N:2, 0] = img_bayer[0:M:2, 0:N:2] # Red pixels
85
+ img[0:M:2, 1:N:2, 1] = img_bayer[0:M:2, 1:N:2] # Green pixels on the first row
86
+ img[1:M:2, 0:N:2, 1] = img_bayer[1:M:2, 0:N:2] # Green pixels on the second row
87
+ img[1:M:2, 1:N:2, 2] = img_bayer[1:M:2, 1:N:2] # Blue pixels
88
+
89
+ # Boundary pixels interpolation in the first and last rows
90
+ # ***Red pixels
91
+ img[0, 2:N-1:2, 1] = (img_bayer[1, 2:N-1:2] + img_bayer[0, 1:N-2:2] + img_bayer[0, 3:N:2] + 1) // 3 # Interpolated G
92
+ img[0, 2:N-1:2, 2] = (img_bayer[1, 1:N-2:2] + img_bayer[1, 3:N:2] + 1) // 2 # Interpolated B
93
+ # ***Green pixels (odd columns)
94
+ img[0, 1:N-2:2, 0] = (img_bayer[0, 0:N-3:2] + img_bayer[0, 2:N-1:2] + 1) // 2 # Interpolated R
95
+ img[0, 1:N-2:2, 2] = img_bayer[1, 1:N-2:2] # Interpolated B
96
+ # ***Blue pixels
97
+ img[M-1, 1:N-2:2, 1] = (img_bayer[M-2, 1:N-2:2]
98
+ + img_bayer[M-1, 0:N-3:2] + img_bayer[M-1, 2:N-1:2] + 1) // 3 # Interpolated G
99
+ img[M-1, 1:N-2:2, 0] = (img_bayer[M-2, 0:N-3:2] + img_bayer[M-2, 2:N-1:2] + 1) // 2 # Interpolated R
100
+ # ***Green pixels (even columns)
101
+ img[M-1, 2:N-1:2, 2] = (img_bayer[M-1, 1:N-2:2] + img_bayer[M-1, 3:N:2] + 1) // 2 # Interpolated B
102
+ img[M-1, 2:N-1:2, 0] = img_bayer[M-2, 2:N-1:2] # Interpolated R
103
+
104
+ # Boundary pixels interpolation in the first and last cols
105
+ # ***Red pixels
106
+ img[2:M-1:2, 0, 1] = (img_bayer[3:M:2, 0] + img_bayer[1:M-2:2, 0] + img_bayer[2:M-1:2, 1] + 1) // 3 # Interpolated G
107
+ img[2:M-1:2, 0, 2] = (img_bayer[3:M:2, 1] + img_bayer[1:M-2:2, 1] + 1) // 2 # Interpolated B
108
+ # ***Green pixels (odd columns)
109
+ img[1:M-2:2, 0, 0] = (img_bayer[0:M-3:2, 0] + img_bayer[2:M-1:2, 0] + 1) // 2 # Interpolated R
110
+ img[1:M-2:2, 0, 2] = img_bayer[1:M-2:2, 1] # Interpolated B
111
+ # ***Blue pixels
112
+ img[1:M-2:2, N-1, 1] = (img_bayer[0:M-3:2, N-1]
113
+ + img_bayer[2:M-1:2, N-1] + img_bayer[1:M-2:2, N-2] + 1) // 3 # Interpolated G
114
+ img[1:M-2:2, N-1, 0] = (img_bayer[0:M-3:2, N-2] + img_bayer[2:M-1:2, N-2] + 1) // 2 # Interpolated R
115
+ # ***Green pixels (even columns)
116
+ img[2:M-1:2, N-1, 0] = img_bayer[2:M-1:2, N-2] # Interpolated R
117
+ img[2:M-1:2, N-1, 2] = (img_bayer[1:M-2:2, N-1]+img_bayer[3:M:2, N-1] + 1)//2 # Interpolated B
118
+
119
+ # Corner pixels interpolation
120
+ # *** top-left
121
+ img[0, 0, 1] = (img_bayer[1, 0] + img_bayer[0, 1] + 1) // 2 # Interpolated G
122
+ img[0, 0, 2] = img_bayer[1, 1] # Interpolated B
123
+ # *** top-right
124
+ img[0, N-1, 0] = img_bayer[0, N-2] # Interpolated R
125
+ img[0, N-1, 2] = img_bayer[1, N-1] # Interpolated B
126
+ # *** bottom-left
127
+ img[M-1, 0, 0] = img_bayer[M-2, 0] # Interpolated R
128
+ img[M-1, 0, 2] = img_bayer[M-1, 1] # Interpolated B
129
+ # *** bottom-right
130
+ img[M-1, N-1, 1] = (img_bayer[M-2, N-1] + img_bayer[M-1, N-2] + 1) // 2 # Interpolated G
131
+ img[M-1, N-1, 0] = img_bayer[M-2, N-2] # Interpolated R
132
+
133
+ # Internal pixels interpolation
134
+ # ***G pixel on odd row, even column
135
+ img[1:M-2:2, 2:N-1:2, 0] = (img_bayer[0:M-3:2, 2:N-1:2] + img_bayer[2:M-1:2, 2:N-1:2] + 1) // 2 # Interpolated R
136
+ img[1:M-2:2, 2:N-1:2, 2] = (img_bayer[1:M-2:2, 1:N-2:2] + img_bayer[1:M-2:2, 3:N:2] + 1) // 2 # Interpolated B
137
+ # ***G pixel on even row, odd column
138
+ img[2:M-1:2, 1:N-2:2, 0] = (img_bayer[2:M-1:2, 0:N-3:2] + img_bayer[2:M-1:2, 2:N-1:2] + 1) // 2 # Interpolated R
139
+ img[2:M-1:2, 1:N-2:2, 2] = (img_bayer[1:M-2:2, 1:N-2:2] + img_bayer[3:M:2, 1:N-2:2] + 1) // 2 # Interpolated B
140
+ # ***R pixel
141
+ img[2:M-1:2, 2:N-1:2, 1] = (img_bayer[1:M-2:2, 2:N-1:2]
142
+ + img_bayer[3:M:2, 2:N-1:2] + img_bayer[2:M-1:2, 1:N-2:2]
143
+ + img_bayer[2:M-1:2, 3:N:2] + 2) // 4 # Interpolated G
144
+ img[2:M-1:2, 2:N-1:2, 2] = (img_bayer[1:M-2:2, 1:N-2:2]
145
+ + img_bayer[3:M:2, 1:N-2:2] + img_bayer[3:M:2, 3:N:2]
146
+ + img_bayer[1:M-2:2, 3:N:2] + 2) // 4 # Interpolated B
147
+ # ***B pixel
148
+ img[1:M-2:2, 1:N-2:2, 0] = (img_bayer[0:M-3:2, 0:N-3:2]
149
+ + img_bayer[2:M-1:2, 0:N-3:2] + img_bayer[2:M-1:2, 2:N-1:2]
150
+ + img_bayer[0:M-3:2, 2:N-1:2] + 2) // 4 # Interpolated R
151
+ img[1:M-2:2, 1:N-2:2, 1] = (img_bayer[0:M-3:2, 1:N-2:2]
152
+ + img_bayer[2:M-1:2, 1:N-2:2] + img_bayer[1:M-2:2, 0:N-3:2]
153
+ + img_bayer[1:M-2:2, 2:N-1:2] + 2) // 4 # Interpolated G
154
+ img_min, img_max = np.min(img), np.max(img)
155
+
156
+ if img_min < 0 or img_max > 255 or (img_max - img_bayer_max) != 0 or (img_min - img_bayer_min) != 0:
157
+ raise ValueError(
158
+ "The converted RGB image is not suitable for further analysis. Check the pixel intensity ranges of the input image."
159
+ )
160
+
161
+ img = img.astype(np.float64) / 255
162
+ return img
163
+
164
+
54
165
  def load_rgb8(filename):
55
166
  '''load an RGB .silc file from disc
56
167
 
@@ -102,13 +213,14 @@ class SilCamLoad():
102
213
  Parameters
103
214
  ----------
104
215
  image_format : str, optional
105
- Image file format. Can be either 'infer', 'rgb8' or 'mono8', by default 'infer'.
216
+ Image file format. Can be either 'infer', 'rgb8', 'bayer_rg8' or 'mono8', by default 'infer'.
106
217
 
107
218
  Note
108
219
  ----
109
220
  'infer' uses the file extension to determine the image format using the following convention:
110
221
  - '.silc' for RGB8
111
222
  - '.msilc' for MONO8
223
+ - '.bsilc' for BAYER_RG8
112
224
  - '.bmp' for using skimage.io.imread
113
225
 
114
226
  Returns
@@ -125,9 +237,10 @@ class SilCamLoad():
125
237
  self.image_format = image_format
126
238
  self.extension_load = {'.silc': load_rgb8,
127
239
  '.msilc': load_mono8,
240
+ '.bsilc': load_bayer_rgb8,
128
241
  '.bmp': skimage.io.imread}
129
242
  self.format_load = {'RGB8': load_rgb8,
130
- 'MONO8': load_mono8}
243
+ 'MONO8': load_mono8, 'BAYER_RG8': load_bayer_rgb8}
131
244
 
132
245
  def __call__(self, data):
133
246
  data['timestamp'] = timestamp_from_filename(data['filename'])
@@ -1 +0,0 @@
1
- __version__ = '2.4.7'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes