PIL image producing array of unexpected size - python

I am writing a program to generate photomosaics and I need the find the average RGB value of an image. I am doing this using distance and numpy as such:
def average_color(image):
"""get the average rgb color of the image"""
npimg = np.array(image)
avg = np.round(np.average(npimg,axis=(0,1)))
return avg
The problem is, for some reason once in a while it produces a numpy.float64 instead of a numpy array. I discovered that the problem came from a weird value of npimg :
[[234 232 244 236 239 240 240 243 238 242]
[237 234 235 234 230 231 235 237 240 243]
[242 239 234 243 248 249 245 238 241 243]
[246 247 246 252 255 255 252 244 248 246]
[250 251 250 254 255 255 254 247 251 249]
[252 253 253 255 255 255 255 253 253 251]
[253 253 251 254 255 255 254 249 253 251]
[252 253 250 253 255 255 253 244 252 249]
[248 245 233 244 246 246 243 228 240 242]
[240 230 225 233 233 234 227 222 224 234]]
When usually it looks like this:
[[252 228 200]
[252 228 200]
[252 228 200]
[251 227 199]
[252 228 200]
[252 228 200]
[253 229 201]
[254 230 202]
[253 230 199]
[253 230 199]]
Why does it do that and how can I solve it ( can I safely use reshape for this job?)

Related

"None" appears before matrix

I wrote a program that generates matrix 7x7 and then rotates it and transposing it. In output i see this "None"
import time
import numpy as np
matsize = np.array([7,7])
matrix = np.random.randint(1000,size=(matsize))
print('\nSwource matrix:\n', matrix, '\n')
rotmatr = np.rot90(matrix, k=-1)
print('Rotation to 90 degrees...\n')
print(time.sleep(2), rotmatr, '\n')
transpos = np.transpose(rotmatr)
print('Transposing...\n')
print(time.sleep(2), transpos)
example of how the code works
Swource matrix:
[[909 859 984 490 773 696 576]
[780 645 632 233 109 181 18]
[ 81 890 328 746 930 45 999]
[944 992 556 436 545 210 814]
[192 827 820 321 45 959 940]
[921 529 276 996 141 132 183]
[235 842 287 169 71 857 70]]
Rotation to 90 degrees...
None [[235 921 192 944 81 780 909]
[842 529 827 992 890 645 859]
[287 276 820 556 328 632 984]
[169 996 321 436 746 233 490]
[ 71 141 45 545 930 109 773]
[857 132 959 210 45 181 696]
[ 70 183 940 814 999 18 576]]
Transposing...
None [[235 842 287 169 71 857 70]
[921 529 276 996 141 132 183]
[192 827 820 321 45 959 940]
[944 992 556 436 545 210 814]
[ 81 890 328 746 930 45 999]
[780 645 632 233 109 181 18]
[909 859 984 490 773 696 576]]
Process finished with exit code 0
What this NONE is and how to delete it???
if you remove the time.sleep(2) from your print statements, that will remove the None
print(time.sleep(2), transpos)
Prints two items:
the return value of time.sleep(2) which is None
the matrix in transpos
To remove None, move the sleep to its own line:
time.sleep(2)
print(transpos)
the problem is the time.sleep(2) just remove it and put it above the print

Numpy Resize Image

I would like to take an image and change the scale of the image, while it is a numpy array.
I would like to do it with native NumPy functions w/o PIL, cv2, SciPy etc
now I have this:
from copy import copy
import numpy as np
from scipy import misc
img = misc.face() # racoon from SciPy(np.ndarray)
img2 = copy(img) # copy of racoon, because misc.face() is Descriptor(?)
img2.shape() # (768, 1024, 3)
Which I need shape = (3072, 4096, 3)
I can do it easy with Pillow
CONVERT_IMAGE = Image.fromarray(img.astype('uint8'), 'RGB')
CONVERT_IMAGE = CONVERT_IMAGE.resize((4096, 3072), Image.NEAREST)
IMAGE_AS_ARRAY = np.asarray(CONVERT_IMAGE)
IMAGE_AS_ARRAY.shape # 3072 4096 3
but I realy need to do this only with NumPy functions w/o other libs
Can you help me ? I'm really weak in NumPy and 3D-arrays
Limited to whole integer upscaling with some scaling factor n and without actual interpolation, you could use np.repeat twice to get the described result:
import numpy as np
# Original image with shape (4, 3, 3)
img = np.random.randint(0, 255, (4, 3, 3), dtype=np.uint8)
# Scaling factor for whole integer upscaling
n = 4
# Actual upscaling (results to some image with shape (16, 12, 3)
img_up = np.repeat(np.repeat(img, n, axis=0), n, axis=1)
# Outputs
print(img[:, :, 1], '\n')
print(img_up[:, :, 1])
Here's some output:
[[148 242 171]
[247 40 152]
[151 131 198]
[ 23 185 144]]
[[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[148 148 148 148 242 242 242 242 171 171 171 171]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[247 247 247 247 40 40 40 40 152 152 152 152]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[151 151 151 151 131 131 131 131 198 198 198 198]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]
[ 23 23 23 23 185 185 185 185 144 144 144 144]]
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
NumPy: 1.19.2
----------------------------------------

Efficient for loop in python

I want to write a for loop in python which iterates for example like 111, 112, 113, 114, 121, 122, 123, 124, 131,.. up to 444. Is there an efficient way to do so?
I tried to convert between decimal and base 4 system but is there a better way to do so?
>>> from itertools import chain
>>> for k in chain.from_iterable(range(i+1, i+5) for i in range(110, 450, 10)):
... print(k)
...
111
112
113
114
121
122
123
124
131
132
133
134
141
142
.
.
.
423
424
431
432
433
434
441
442
443
444
SO like this:
[ i for i in range(111, 445) if '0' < str(i)[-1] < '5']
you can use:
[ i for i in range(111, 445) if 0< i%(i-i%10) <5]
You can convert a range of integers to base 4 using base_repr from numpy:
import numpy
for i in range(64):
print(int(numpy.base_repr(i, base=4)) + 111)
Output:
111
112
113
114
121
122
123
124
131
132
133
134
141
142
143
144
211
212
213
214
221
222
223
224
231
232
233
234
241
242
243
244
311
312
313
314
321
322
323
324
331
332
333
334
341
342
343
344
411
412
413
414
421
422
423
424
431
432
433
434
441
442
443
444

Feature extraction of image by ORB

I want to extract features of text in an image ,
I applied otsu thresholding , followed by erosion ,dilation , found contours and drew them
In the end I used ORB algortithm on preprocessed image
def ORB_descp(ppi):
orb = cv2.ORB_create()
kp = orb.detect(ppi,None)
kp, des = orb.compute(ppi, kp)
return cv2.drawKeypoints(ppi,kp,None,color=(0,255,0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS),kp,des
now i printed des in above code and i got a 2D array where each array within 2D array contains 32 integer something like that
des= [ [180 246 202 86 211 123 167 253 114 159 100 222 64 224 239 159 57 206
130 186 113 247 188 106 56 7 101 45 233 121 238 176] ,................
..,[189 127 34 83 211 191 182 220 55 110 125 255 74 245 239 156 61 250
135 246 254 182 56 62 123 205 37 231 251 247 238 215] ]
What is this array of des,are they features of image ?
If they are how can I use them for text recognition and if not how can I extract feature of text in image for text recognition .
I have to use these features to train SVM , but I am struck at this point
I am not able to extract features.

Don't understand the result I have with pytesseract

I'm trying to read the following image :
try:
import Image
except ImportError:
from PIL import Image
import pytesseract as tes
results = tes.image_to_string(Image.open('./test.png'),boxes=True)
print(results)
And here is the result I have :
_ 239 780 263 787 0
. 239 758 263 767 0
L 235 737 263 761 0
1 220 763 229 783 0
1 220 741 229 761 0
‘ 129 763 137 784 0
1 129 741 136 761 0
1 220 650 229 670 0
‘ 220 628 229 648 0
F 235 537 263 561 0
. 239 531 263 540 0
A 239 511 268 534 0
_ 199 554 223 561 0
I 260 401 268 421 0
r 235 424 263 448 0
. 239 418 263 427 0
_ 239 398 263 404 0
{ 220 424 229 444 0
I 220 401 229 421 0
“ 220 288 229 331 0
What does this mean ? How I can interpret this result ?
Thanks a lot!
As you set boxes=True in tes.image_to_string(), the output is in box file format which the first letter in the line is the character recognized and then the bounding box coordinates of an occurrence of that character in the image. If boxes=False, tesseract will only output the characters recognized.
The image you are trying to OCR is the 7-segment digits, you may need to have a trained (language) data for 7-segment digits in order to get a good result.

Categories

Resources