05-05-2023, 08:13 AM
Hola a todos.
Tengo un código de python que secciona las imágenes almacenadas en una carpeta de google drive en varias partes predefinidas por coordenadas si cumple cierta condición de color de la imagen. Una vez seccionadas y pasadas a escala de grises, las almacena en otra carpeta de google drive. Aparentemente funciona correctamente, porque secciona las imágenes perfectamente porque luego las puedes visualizar con cualquier programa de visualización o edición de imágenes.
El caso, es que luego esas imágenes las convierto a google docs para poder extraer el texto de cada imagen y aquí es donde me viene el problema, la gran mayoría de las imágenes las reconoce bien y me extrae el texto, con mejor o peor acierto, pero hay algunas que no las reconoce google docs. Ojo, cuando digo que no las reconoce, no digo que el texto que extrae este en blanco, sino que no reconoce el archivo de imagen. Esto lo digo, porque cuando abres una imagen en google docs, te genera un documento encabezado por la imagen y debajo de esta añade el texto extraído de la misma. Cuando no reconoce la imagen, genera un doc totalmente en blanco, sin el encabezado de la imagen, que por lo menos debería estar.
He probado, subir la resolución, como veréis en el código, pero no he conseguido mejorar el resultado. Al final, siempre me genera un pequeño grupo de imágenes que no acaba reconociendo google docs.
Para dar más información, decir que las imágenes originales que secciono, son imágenes jpg de pantallazos de móvil. Que en total acaba seccionando unas 100 imágenes como máximo de una vez.
A continuación os dejo el código para ver si alguien puede ayudarme a resolver el problema. Gracias de antemano.
Tengo un código de python que secciona las imágenes almacenadas en una carpeta de google drive en varias partes predefinidas por coordenadas si cumple cierta condición de color de la imagen. Una vez seccionadas y pasadas a escala de grises, las almacena en otra carpeta de google drive. Aparentemente funciona correctamente, porque secciona las imágenes perfectamente porque luego las puedes visualizar con cualquier programa de visualización o edición de imágenes.
El caso, es que luego esas imágenes las convierto a google docs para poder extraer el texto de cada imagen y aquí es donde me viene el problema, la gran mayoría de las imágenes las reconoce bien y me extrae el texto, con mejor o peor acierto, pero hay algunas que no las reconoce google docs. Ojo, cuando digo que no las reconoce, no digo que el texto que extrae este en blanco, sino que no reconoce el archivo de imagen. Esto lo digo, porque cuando abres una imagen en google docs, te genera un documento encabezado por la imagen y debajo de esta añade el texto extraído de la misma. Cuando no reconoce la imagen, genera un doc totalmente en blanco, sin el encabezado de la imagen, que por lo menos debería estar.
He probado, subir la resolución, como veréis en el código, pero no he conseguido mejorar el resultado. Al final, siempre me genera un pequeño grupo de imágenes que no acaba reconociendo google docs.
Para dar más información, decir que las imágenes originales que secciono, son imágenes jpg de pantallazos de móvil. Que en total acaba seccionando unas 100 imágenes como máximo de una vez.
A continuación os dejo el código para ver si alguien puede ayudarme a resolver el problema. Gracias de antemano.
Código:
def get_dominant_colors(image):
"""
Retorna los 3 colores predominantes de una imagen
"""
pixels = image.getcolors(image.size[0] * image.size[1])
sorted_pixels = sorted(pixels, key=lambda t: t[0], reverse=True)
return [color[1] for color in sorted_pixels[:10]]
def is_color_in_range(color, range1, range2):
"""
Retorna True si el color se encuentra en un rango de tonos que incluya range1 y range2
"""
r, g, b = color
return ((r >= range1[0] and r <= range2[0]) and
(g >= range1[1] and g <= range2[1]) and
(b >= range1[2] and b <= range2[2]) and
color != (255, 255, 255))
def divide_imagenes3(creds, origen_id, destino_id, nombre_equipo):
coordenadas_2400 = [(810, 300, 1100, 390), (810, 385, 1100, 475), (810, 470, 1100, 560), (810, 555, 1100, 645), (810, 635, 1100, 730), (810, 720, 1100, 810), (810, 810, 1100, 890)]
coordenadas_2400_2 = [(1340, 300, 1490, 390), (1340, 385, 1490, 475), (1340, 470, 1490, 560), (1340, 555, 1490, 645), (1340, 635, 1490, 730), (1340, 720, 1490, 810), (1340, 810, 1490, 890)]
coordenadas_4800 = [(1620, 600, 2200, 780), (1620, 770, 2200, 950), (1620, 940, 2200, 1120), (1620, 1110, 2200, 1290), (1620, 1270, 2200, 1460), (1620, 1440, 2200, 1620), (1620, 1620, 2200, 1780)]
coordenadas_4800_2 = [(2680, 600, 2980, 780), (2680, 770, 2980, 950), (2680, 940, 2980, 1120), (2680, 1110, 2980, 1290), (2680, 1270, 2980, 1460), (2680, 1440, 2980, 1620), (2680, 1620, 2980, 1780)]
coordenadas_7200 = [(2430, 900, 3300, 1170), (2430, 1155, 3300, 1425), (2430, 1410, 3300, 1680), (2430, 1665, 3300, 1935), (2430, 1905, 3300, 2190), (2430, 2160, 3300, 2430), (2430, 2430, 3300, 2670)]
coordenadas_7200_2 = [(4020, 900, 4470, 1170), (4020, 1155, 4470, 1425), (4020, 1410, 4470, 1680), (4020, 1665, 4470, 1935), (4020, 1905, 4470, 2190), (4020, 2160, 4470, 2430), (4020, 2430, 4470, 2670)]
coordenadas_9600 = [(3240, 1200, 4400, 1560), (3240, 1540, 4400, 1900), (3240, 1880, 4400, 2240), (3240, 2220, 4400, 2580), (3240, 2540, 4400, 2920), (3240, 2880, 4400, 3240), (3240, 3240, 4400, 3560)]
coordenadas_9600_2 = [(5360, 1200, 5960, 1560), (5360, 1540, 5960, 1900), (5360, 1880, 5960, 2240), (5360, 2220, 5960, 2580), (5360, 2540, 5960, 2920), (5360, 2880, 5960, 3240), (5360, 3240, 5960, 3560)]
ocre_range = ((120, 120, 70), (200, 200, 120))
amarillo_range = ((200, 200, 115), (245, 245, 200))
ama_range = ((190, 190, 115), (225, 230, 140))
blanco_range = ((246, 246, 246), (255, 255, 255))
temp_file_path = None # Inicializamos la variable con None
try:
service = build('drive', 'v3', credentials=creds)
query = f"'{origen_id}' in parents"
results = service.files().list(q=query, fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
for n, item in enumerate(items):
if not item['name'].lower().endswith(('.jpg', '.jpeg')):
continue
if item['name'] == '666.jpg':
continue
file_id = item['id']
file_name = item['name']
response = service.files().get_media(fileId=file_id).execute()
image_bytes = io.BytesIO(response)
image = Image.open(image_bytes)
if image.size == (2400, 1080) and nombre_equipo == 'UNIÓN~H1':
coordenadas = coordenadas_2400
coordenadas2 = coordenadas_2400_2
elif image.size == (4800, 2160) and nombre_equipo == 'UNIÓN~H1':
coordenadas = coordenadas_4800
coordenadas2 = coordenadas_4800_2
elif image.size == (7200, 3240) and nombre_equipo == 'UNIÓN~H1':
coordenadas = coordenadas_7200
coordenadas2 = coordenadas_7200_2
elif image.size == (9600, 4320) and nombre_equipo == 'UNIÓN~H1':
coordenadas = coordenadas_9600
coordenadas2 = coordenadas_9600_2
else:
continue
time.sleep(2)
image = Image.open(image_bytes)
for i in range(7):
x1, y1, x2, y2 = coordenadas[i]
part = image.crop((x1, y1, x2, y2))
colors = get_dominant_colors(part)
is_color_in_range_flag = False
for color in colors:
if (is_color_in_range(color, ocre_range[0], ocre_range[1]) or is_color_in_range(color, amarillo_range[0], amarillo_range[1]) or is_color_in_range(color, ama_range[0], ama_range[1])) and color != (255, 255, 255):
is_color_in_range_flag = True
break
if is_color_in_range_flag:
part = part.convert('L')
temp_file_path = f'{uuid.uuid4()}.jpg'
with open(temp_file_path, 'wb') as f:
part.save(f, format='JPEG', quality=100, optimize=True, resolution=300)
with Image.open(temp_file_path) as temp_image:
enhancer = ImageEnhance.Contrast(temp_image)
temp_image = enhancer.enhance(1.5)
temp_image.save(temp_file_path, quality=100, optimize=True, resolution=300)
new_file_name = f'{n+1}.{i+1}.png'
file_metadata = {'name': new_file_name, 'parents': [destino_id]}
with open(temp_file_path, 'rb') as f:
media = googleapiclient.http.MediaIoBaseUpload(io.BytesIO(f.read()), mimetype='image/png', chunksize=1024*1024, resumable=True)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
image = Image.open(image_bytes)
for j in range(len(coordenadas2)):
if j == i: # comprobamos si seccionamos la coordenada correspondiente en la primera variable
x1, y1, x2, y2 = coordenadas2[j]
part2 = image.crop((x1, y1, x2, y2))
colors2 = get_dominant_colors(part2)
is_color_in_range_flag2 = False
for color in colors2:
if color != (255, 255, 255):
is_color_in_range_flag2 = True
break
if is_color_in_range_flag2:
part2 = part2.convert('L')
temp_file_path = f'{uuid.uuid4()}.jpg'
with open(temp_file_path, 'wb') as f:
part2.save(f, format='JPEG', quality=100, optimize=True, resolution=300)
with Image.open(temp_file_path) as temp_image:
enhancer = ImageEnhance.Contrast(temp_image)
temp_image = enhancer.enhance(1.5)
temp_image.save(temp_file_path, quality=100, optimize=True, resolution=300)
new_file_name2 = f'{n+1}.{1}{j+1}.png'
file_metadata2 = {'name': new_file_name2, 'parents': [destino_id]}
with open(temp_file_path, 'rb') as f:
media2 = googleapiclient.http.MediaIoBaseUpload(io.BytesIO(f.read()), mimetype='image/png', chunksize=1024*1024, resumable=True)
file2 = service.files().create(body=file_metadata2, media_body=media2, fields='id').execute()
break
else:
continue
except HttpError as error:
print(f'Error en la API de Drive: {error}')
except Exception as e:
print(f'Ha ocurrido un error inesperado: {e}')
finally:
if temp_file_path is not None: # Verificamos que la variable tenga un valor antes de intentar eliminarla
os.remove(temp_file_path) # borramos archivo temporal creado