Saltar al contenido

Historial del chat

Nuevo chat

Buscar chats

Ctrl K

Biblioteca

Photo Realistic Image GPT

GPT

Sora

Nuevo proyecto

Hoy

Traducir al ingles automated_morph_all

7 días anteriores

Wrapper VB.NET solicitud

Renovación Plan Astrix Chats

Problemas con suscripción Plus

Ver planes

Acceso ilimitado, características de Team y más

Abrir barra lateral

ChatGPT o4-mini-high

ChatGPT o4-mini-high

Compartir

PLUS

Dijiste:

Me podrias dar este codigo, sin cambiar nada en absoluto salvo todos lso c=mensajes y comentarios en ingles?
//////////////////
import cv2
import numpy as np
import os
import argparse
import dlib

###############################
# ORB + RANSAC
###############################
def detect_orb_features(img1, img2, max_features=500):
"""
Detecta y empareja características ORB en ambas imágenes.
Retorna dos listas de puntos (x, y) correspondientes: pts1, pts2.
"""
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
orb = cv2.ORB_create(nfeatures=max_features)
kp1, des1 = orb.detectAndCompute(gray1, None)
kp2, des2 = orb.detectAndCompute(gray2, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
pts1 = []
pts2 = []
for m in matches:
x1, y1 = kp1[m.queryIdx].pt
x2, y2 = kp2[m.trainIdx].pt
pts1.append((x1, y1))
pts2.append((x2, y2))
return pts1, pts2

def filter_matches_ransac(pts1, pts2, reproj_threshold=5.0):
"""
Aplica RANSAC para filtrar outliers en las correspondencias.
Retorna listas filtradas: pts1_inliers, pts2_inliers.
"""
if len(pts1) < 4:
return pts1, pts2
pts1_np = np.float32(pts1)
pts2_np = np.float32(pts2)
H, mask = cv2.findHomography(pts1_np, pts2_np, cv2.RANSAC, reproj_threshold)
if mask is None:
return pts1, pts2
inliers1 = []
inliers2 = []
for i, m in enumerate(mask):
if m == 1:
inliers1.append(tuple(pts1[i]))
inliers2.append(tuple(pts2[i]))
return inliers1, inliers2

###############################
# Landmarks y bounding box
###############################
def detectLandmarksAndRect(image_path, predictor_path):
"""
Detecta la cara en la imagen con dlib y extrae 68 landmarks faciales.
Retorna (points, face_rect), donde face_rect es (x, y, w, h).
"""
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 1)
if len(rects) == 0:
raise Exception(f"No se detectó ningún rostro en {image_path}")
dlib_rect = rects[0]
shape = predictor(gray, dlib_rect)
points = []
for i in range(68):
points.append((shape.part(i).x, shape.part(i).y))
face_rect = (dlib_rect.left(), dlib_rect.top(), dlib_rect.width(), dlib_rect.height())
return points, face_rect

def readPoints(path):
"""Lee puntos (landmarks) desde un archivo de texto."""
points = []
with open(path) as file:
for line in file:
x, y = line.split()
points.append((int(x), int(y)))
return points

def writePoints(path, points):
"""Guarda la lista de puntos en un archivo de texto."""
with open(path, "w") as file:
for (x, y) in points:
file.write(f"{x} {y}\n")

###############################
# Añadir esquinas y bordes
###############################
def addBorderPoints(points, width, height):
"""Añade las cuatro esquinas de la imagen a la lista de puntos."""
points.append((0, 0))
points.append((width - 1, 0))
points.append((0, height - 1))
points.append((width - 1, height - 1))

def addEdgePoints(points, width, height, step=50):
"""
Añade puntos a lo largo de los bordes con un salto 'step'.
"""
# Borde superior
for x in range(step, width - 1, step):
points.append((x, 0))
# Borde inferior
for x in range(step, width - 1, step):
points.append((x, height - 1))
# Borde izquierdo
for y in range(step, height - 1, step):
points.append((0, y))
# Borde derecho
for y in range(step, height - 1, step):
points.append((width - 1, y))

###############################
# Excluir ORB en la cara
###############################
def filter_orb_in_face(pts1, pts2, face_rect1, face_rect2, margin=0):
"""
Excluye los puntos ORB que caigan dentro del rectángulo facial.
face_rect es (x, y, w, h).
"""
x1, y1, w1, h1 = face_rect1
x2, y2, w2, h2 = face_rect2
filtered1 = []
filtered2 = []
for (px, py), (qx, qy) in zip(pts1, pts2):
inside1 = (x1 - margin <= px <= x1 + w1 + margin and
y1 - margin <= py <= y1 + h1 + margin)
inside2 = (x2 - margin <= qx <= x2 + w2 + margin and
y2 - margin <= qy <= y2 + h2 + margin)
if not (inside1 or inside2):
filtered1.append((px, py))
filtered2.append((qx, qy))
return filtered1, filtered2

###############################
# Triangulación y morphing
###############################
def find_index(points, point, eps=1.0):
"""Busca en 'points' un punto que esté a menos de 'eps' de 'point'."""
for i, p in enumerate(points):
if abs(p[0] - point[0]) < eps and abs(p[1] - point[1]) < eps:
return i
return None

def generateDelaunayTriangles(points, width, height):
"""
Genera la triangulación de Delaunay a partir de una lista de puntos en un rectángulo (0,0,width,height).
Retorna una lista de triángulos (índices).
"""
rect = (0, 0, width, height)
subdiv = cv2.Subdiv2D(rect)
for p in points:
subdiv.insert(p)
triangleList = subdiv.getTriangleList()
triangles = []
for t in triangleList:
pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])
index1 = find_index(points, pt1)
index2 = find_index(points, pt2)
index3 = find_index(points, pt3)
if index1 is not None and index2 is not None and index3 is not None:
triangles.append((index1, index2, index3))
return triangles

def applyAffineTransform(src, srcTri, dstTri, size):
"""Aplica una transformación afín de srcTri a dstTri sobre src."""
warpMat = cv2.getAffineTransform(np.float32(srcTri), np.float32(dstTri))
dst = cv2.warpAffine(src, warpMat, (size[0], size[1]), None,
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REFLECT_101)
return dst

def morphTriangle(img1, img2, img, t1, t2, t, alpha):
"""Realiza el morphing de un triángulo y copia el resultado en 'img'."""
r1 = cv2.boundingRect(np.float32([t1]))
r2 = cv2.boundingRect(np.float32([t2]))
r = cv2.boundingRect(np.float32([t]))

tRect = []
t1Rect = []
t2Rect = []
for i in range(3):
tRect.append((t[i][0] - r[0], t[i][1] - r[1]))
t1Rect.append((t1[i][0] - r1[0], t1[i][1] - r1[1]))
t2Rect.append((t2[i][0] - r2[0], t2[i][1] - r2[1]))

mask = np.zeros((r[3], r[2], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(tRect), (1.0, 1.0, 1.0), 16, 0)

img1Rect = img1[r1[1]:r1[1]+r1[3], r1[0]:r1[0]+r1[2]]
img2Rect = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]]
size = (r[2], r[3])
warpImage1 = applyAffineTransform(img1Rect, t1Rect, tRect, size)
warpImage2 = applyAffineTransform(img2Rect, t2Rect, tRect, size)

imgRect = (1.0 - alpha) * warpImage1 + alpha * warpImage2

existing = img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]]
img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = existing * (1 - mask) + imgRect * mask

###############################
# Programa principal
###############################
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Morph global con landmarks faciales, ORB + RANSAC, y puntos en bordes, excluyendo la zona facial de ORB.")
parser.add_argument('--src', required=True, help='Ruta a la imagen fuente (ej. C:\\imagen1.jpg)')
parser.add_argument('--dest', required=True, help='Ruta a la imagen destino (ej. C:\\imagen2.jpg)')
parser.add_argument('--frames', type=int, default=30, help='Número de fotogramas intermedios')
parser.add_argument('--output', required=True, help='Ruta al video de salida (ej. C:\\salida2.mp4)')
parser.add_argument('--predictor', required=True, help='Ruta al archivo del predictor dlib (ej. shape_predictor_68_face_landmarks.dat)')
parser.add_argument('--orbfeatures', type=int, default=500, help='Número máximo de características ORB')
parser.add_argument('--ransac', type=float, default=5.0, help='Umbral de reproyección RANSAC')
parser.add_argument('--edgestep', type=int, default=50, help='Salto para añadir puntos en bordes')
parser.add_argument('--marginface', type=int, default=0, help='Margen para excluir puntos ORB dentro de la cara')
parser.add_argument('--fps', type=int, default=30, help='FPS de salida del video')
args = parser.parse_args()

# 1) Cargar imágenes (uint8 para ORB, float32 para morph)
img1_uint8 = cv2.imread(args.src)
img2_uint8 = cv2.imread(args.dest)
if img1_uint8 is None or img2_uint8 is None:
raise Exception("Error al cargar las imágenes. Revisa las rutas.")

height, width, _ = img1_uint8.shape
img1 = np.float32(img1_uint8)
img2 = np.float32(img2_uint8)

# 2) Detectar landmarks y bounding box (si existen .txt se eliminan para recalcular)
landmarks_path1 = args.src + '.txt'
landmarks_path2 = args.dest + '.txt'

for path in (landmarks_path1, landmarks_path2):
try:
os.remove(path)
except FileNotFoundError:
# Si no existe, lo ignoramos
pass
except Exception as e:
# Para otros errores (permisos, uso por otro proceso, etc.)
print(f"Advertencia borrando {path}: {e}")

points1, rect1 = detectLandmarksAndRect(args.src, args.predictor)
writePoints(landmarks_path1, points1)
points2, rect2 = detectLandmarksAndRect(args.dest, args.predictor)
writePoints(landmarks_path2, points2)

# 3) Añadir esquinas y puntos en los bordes
addBorderPoints(points1, width, height)
addEdgePoints(points1, width, height, step=args.edgestep)
addBorderPoints(points2, width, height)
addEdgePoints(points2, width, height, step=args.edgestep)

# 4) ORB y RANSAC para el resto de la imagen, excluyendo la zona facial
pts1_orb, pts2_orb = detect_orb_features(img1_uint8, img2_uint8, max_features=args.orbfeatures)
pts1_orb_filtered, pts2_orb_filtered = filter_matches_ransac(pts1_orb, pts2_orb, reproj_threshold=args.ransac)
pts1_orb_final, pts2_orb_final = filter_orb_in_face(
pts1_orb_filtered, pts2_orb_filtered,
rect1, rect2, margin=args.marginface
)
for (x, y) in pts1_orb_final:
points1.append((x, y))
for (x, y) in pts2_orb_final:
points2.append((x, y))

if len(points1) != len(points2):
raise Exception("La cantidad de puntos en points1 y points2 no coincide tras filtrar ORB.")

# 5) Generar puntos promedio para la triangulación
avgPoints = []
for i in range(len(points1)):
avgPoints.append(((points1[i][0] + points2[i][0]) / 2.0,
(points1[i][1] + points2[i][1]) / 2.0))

# 6) Triangulación de Delaunay
triangles = generateDelaunayTriangles(avgPoints, width, height)
if not triangles:
raise RuntimeError("No se generaron triángulos de Delaunay; revisa los puntos.")

# 7) Configurar VideoWriter con FPS especificado
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = args.fps
video_writer = cv2.VideoWriter(args.output, fourcc, fps, (width, height))

# 8) Generar frames
n_frames = args.frames
for f in range(n_frames + 1):
alpha = f / float(n_frames)
imgMorph = np.zeros_like(img1, dtype=np.float32)

# Interpolar puntos
interpPoints = []
for i in range(len(points1)):
x = (1 - alpha) * points1[i][0] + alpha * points2[i][0]
y = (1 - alpha) * points1[i][1] + alpha * points2[i][1]
interpPoints.append((x, y))

# Morph en cada triángulo
for (i, j, k) in triangles:
t1 = [points1[i], points1[j], points1[k]]
t2 = [points2[i], points2[j], points2[k]]
t = [interpPoints[i], interpPoints[j], interpPoints[k]]
morphTriangle(img1, img2, imgMorph, t1, t2, t, alpha)

frame_uint8 = np.uint8(imgMorph)
video_writer.write(frame_uint8)
print(f"Frame {f} generado.")

video_writer.release()
try:
cv2.destroyAllWindows()
except Exception:
# Si no está implementado (build headless), lo ignoramos
pass
print("Video generado exitosamente:", args.output)
///////////////////

ChatGPT dijo:

Pensado durante 1m 41s

Morphing Orb Ransac

999

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

import cv2

import numpy as np

import os

import argparse

import dlib

###############################

# ORB + RANSAC

###############################

def detect_orb_features(img1, img2, max_features=500):

"""

Detects and matches ORB features in both images.

Returns two lists of corresponding points (x, y): pts1, pts2.

"""

gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

orb = cv2.ORB_create(nfeatures=max_features)

kp1, des1 = orb.detectAndCompute(gray1, None)

kp2, des2 = orb.detectAndCompute(gray2, None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

matches = bf.match(des1, des2)

matches = sorted(matches, key=lambda x: x.distance)

pts1 = []

pts2 = []

for m in matches:

x1, y1 = kp1[m.queryIdx].pt

x2, y2 = kp2[m.trainIdx].pt

pts1.append((x1, y1))

pts2.append((x2, y2))

return pts1, pts2

def filter_matches_ransac(pts1, pts2, reproj_threshold=5.0):

"""

Applies RANSAC to filter outliers in the matches.

Returns filtered lists: pts1_inliers, pts2_inliers.

"""

I’ve translated all comments, docstrings, help messages, and print/exception strings to English while keeping the code logic unchanged. Let me know if you need any further adjustments!

Dijiste:

Ok, thaks, gracias, y tenia esto para compilarlo:
automated_morph_all_new.spec
# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
['C:\\automated_morph_all.pyQue estaba mas o menos Bien el 27 marzo 2025b.py'],
pathex=[],
binaries=[],
datas=[('shape_predictor_68_face_landmarks.dat', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)

exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='automated_morph_all_new',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

Como lo compilo de neubvo para que este todo en ingles?

ChatGPT dijo:

Pensado durante 5 segundos

First, make sure you’ve saved your translated script under a clean, English-only filename (for example automated_morph_all.py). Then:

Edit the .spec

Open automated_morph_all_new.spec and in the Analysis section replace that messy path…

diff

CopiarEditar

- ['C:\\automated_morph_all.pyQue estaba mas o menos Bien el 27 marzo 2025b.py'],
+ ['C:\\path\\to\\automated_morph_all.py'],

and leave the rest (your datas=[('shape_predictor_68_face_landmarks.dat', '.')], etc.) untouched.

Re-build with PyInstaller

From a terminal (on Windows, PowerShell or cmd), cd into the folder containing your .spec and run:

bash

CopiarEditar

pyinstaller automated_morph_all_new.spec

PyInstaller will read that spec, bundle your newly translated script plus the .dat file, and spit out dist\automated_morph_all_new\automated_morph_all_new.exe.

Test

bash

CopiarEditar

dist\automated_morph_all_new\automated_morph_all_new.exe --help

You should see your English usage/help messages.

If you ever rename the script again or move the .dat file, just update the path in the Analysis([...]) line of the .spec and re-run the same pyinstaller …spec command.

Dijiste:

En el chat en Español por favor, en lso codigos en ingles todo lo que sena comentarios, prints etc que no internivienen con el codigo

ChatGPT dijo:

Pensado durante 10 segundos

Claro. A partir de aquí te respondo en español, y los fragmentos de código los dejo con sus comentarios y textos en inglés tal como los tienes.

1. Renombra tu script traducido a algo “limpio”

Por ejemplo:

text

CopiarEditar

C:\path\to\automated_morph_all.py

2. Edita el .spec

Abre automated_morph_all_new.spec y en la sección Analysis sustituye la ruta al viejo fichero por la de tu nuevo script. Quedaría así (mantén el resto tal cual):

python

CopiarEditar

# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
['C:\\path\\to\\automated_morph_all.py'], # apunta al script ya traducido
pathex=[],
binaries=[],
datas=[('shape_predictor_68_face_landmarks.dat', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)

exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='automated_morph_all_new',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

3. Vuelve a compilar con PyInstaller

Desde una consola (cmd o PowerShell), sitúate en la carpeta donde esté tu .spec y ejecuta:

bash

CopiarEditar

pyinstaller automated_morph_all_new.spec

PyInstaller leerá la espec y generará el ejecutable en:

CopiarEditar

dist\automated_morph_all_new\automated_morph_all_new.exe

4. Verifica que todo esté en inglés

Ejecuta el help para comprobar tus mensajes:

bash

CopiarEditar

dist\automated_morph_all_new\automated_morph_all_new.exe --help

Ahí deberían aparecer tus descripciones, prints y warnings en inglés, tal y como quedaron en el script.

Cada vez que renombres o muevas tu script, solo actualiza la ruta en a = Analysis([ … ]) dentro del .spec y repite el comando de PyInstaller.

Dijiste:

Ahh, se em olvidaba, como incluirle mi propio icon, hay que modificar el spec? o el pyinstaller?

ChatGPT dijo:

Pensado durante 10 segundos

Para incluir tu propio icono tienes dos opciones:

1. Usando la línea de comandos de PyInstaller

Si no quieres tocar el .spec, basta con pasar el parámetro --icon al invocar PyInstaller. Por ejemplo:

bash

CopiarEditar

pyinstaller --icon=C:\path\to\my_icon.ico automated_morph_all.py

Esto generará el exe (y actualizará también el spec internamente si no existe) con tu icono.

2. Editando el .spec directamente

Si ya estás usando tu automated_morph_all_new.spec, lo más claro es añadir el parámetro icon= dentro de la llamada a EXE(...). Quedaría así:

python

CopiarEditar

# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
['C:\\path\\to\\automated_morph_all.py'],
pathex=[],
binaries=[],
datas=[('shape_predictor_68_face_landmarks.dat', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)

pyz = PYZ(a.pure)

exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='automated_morph_all_new',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='C:\\path\\to\\my_icon.ico', # your custom icon here
)

Después, en la misma carpeta del .spec, vuelves a lanzar:

bash

CopiarEditar

pyinstaller automated_morph_all_new.spec

y tu ejecutable saldrá con el icono que hayas indicado.

En resumen:

CLI: --icon=... al invocar PyInstaller.

Spec: añadir icon='ruta/a/tu_icono.ico' en el bloque EXE(...).

Escoge la que te resulte más cómoda.

Dijiste:

Perdona, y con upx?

ChatGPT dijo:

Pensado durante 11 segundos

Para que PyInstaller comprima tu ejecutable con UPX, asegúrate de:

Tener UPX instalado

Descarga e instala UPX (por ejemplo en C:\upx) y añade esa carpeta al PATH de Windows. PyInstaller lo detecta automáticamente.

Especificarlo en la línea de comandos

Si quieres indicarle a PyInstaller dónde está UPX, o desactivar la compresión, puedes usar estas opciones:

bash

CopiarEditar

# Usar UPX (si está en PATH, no necesitas --upx-dir)
pyinstaller --icon=C:\path\to\my_icon.ico automated_morph_all.py

# O, si UPX está en una ruta no estándar:
pyinstaller --upx-dir=C:\upx --icon=C:\path\to\my_icon.ico automated_morph_all.py

# Si por alguna razón quieres **desactivar** UPX:
pyinstaller --noupx --icon=C:\path\to\my_icon.ico automated_morph_all.py

O bien, configurarlo en el .spec

Ya tienes en tu EXE(...) la línea upx=True. Si quieres usar un directorio distinto de UPX o desactivar, modifica así:

python

CopiarEditar

exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='automated_morph_all_new',
debug=False,
strip=False,
console=True,
upx=True, # True = comprime con UPX si lo encuentra
upx_exclude=['something.dll'], # opcional: excluye ficheros de la compresión
# Si quisieras desactivar UPX, pon:
# upx=False,
# Si necesitas indicar un path de UPX, en spec no hay parámetro directo,
# se usaría --upx-dir en la línea de comandos al invocar pyinstaller:
# pyinstaller --upx-dir=C:\upx automated_morph_all_new.spec
icon='C:\\path\\to\\my_icon.ico',
)

Recompilar

bash

CopiarEditar

pyinstaller --upx-dir=C:\upx automated_morph_all_new.spec

Con esto tu .exe saldrá comprimido con UPX (si está disponible) y tendrá el icono que indiques.

Dijiste:

automated_morph_all.spec

Archivo

Mira, tengo este nuevo spec que te paso, pero no em crea el exe con el icono mio, porque?

ChatGPT dijo:

Pensado durante 15 segundos

Puede que el problema sea principalmente cómo Python está interpretando la ruta que pusiste en el spec. Ahora mismo tienes:

python

CopiarEditar

icon='C:\zodiac399ico.ico',

Pero en un literal de Python la secuencia \z no es un “escape” válido, así que al cargar el spec el string se desvirtúa y PyInstaller acaba ignorando tu icono.

Solución: escapa las barras (o usa cadenas “raw”) y asegúrate de que el fichero realmente exista en esa ruta al momento de compilar:

diff

CopiarEditar

exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='automated_morph_all',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
- icon='C:\zodiac399ico.ico',
+ # Opción A: escapando barras
+ icon='C:\\zodiac399ico.ico',
+ # Opción B: raw string
+ # icon=r'C:\zodiac399ico.ico',
)

Escapado de barras: cada \ pasa a ser \\.

Raw string: delante de la comilla pones r'…' para que no se interpreten escapes.

Después vuelve a ejecutar:

bash

CopiarEditar

pyinstaller --clean automated_morph_all.spec

– --clean asegura que no reutilice cachés viejos.

Al finalizar, tu dist\automated_morph_all\automated_morph_all.exe debería llevar el icono correcto.

Dijiste:

Y como podria ponerle colores a los print de este python?
import cv2
import numpy as np
import os
import argparse
import dlib

###############################
# ORB + RANSAC
###############################
def detect_orb_features(img1, img2, max_features=500):
"""
Detects and matches ORB features in both images.
Returns two lists of corresponding points (x, y): pts1, pts2.
"""
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
orb = cv2.ORB_create(nfeatures=max_features)
kp1, des1 = orb.detectAndCompute(gray1, None)
kp2, des2 = orb.detectAndCompute(gray2, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
pts1 = []
pts2 = []
for m in matches:
x1, y1 = kp1[m.queryIdx].pt
x2, y2 = kp2[m.trainIdx].pt
pts1.append((x1, y1))
pts2.append((x2, y2))
return pts1, pts2

def filter_matches_ransac(pts1, pts2, reproj_threshold=5.0):
"""
Applies RANSAC to filter outliers in the matches.
Returns filtered lists: pts1_inliers, pts2_inliers.
"""
if len(pts1) < 4:
return pts1, pts2
pts1_np = np.float32(pts1)
pts2_np = np.float32(pts2)
H, mask = cv2.findHomography(pts1_np, pts2_np, cv2.RANSAC, reproj_threshold)
if mask is None:
return pts1, pts2
inliers1 = []
inliers2 = []
for i, m in enumerate(mask):
if m == 1:
inliers1.append(tuple(pts1[i]))
inliers2.append(tuple(pts2[i]))
return inliers1, inliers2

###############################
# Face landmarks and bounding box
###############################
def detectLandmarksAndRect(image_path, predictor_path):
"""
Detects the face in the image using dlib and extracts 68 facial landmarks.
Returns (points, face_rect), where face_rect is (x, y, w, h).
"""
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 1)
if len(rects) == 0:
raise Exception(f"No face detected in {image_path}")
dlib_rect = rects[0]
shape = predictor(gray, dlib_rect)
points = []
for i in range(68):
points.append((shape.part(i).x, shape.part(i).y))
face_rect = (dlib_rect.left(), dlib_rect.top(), dlib_rect.width(), dlib_rect.height())
return points, face_rect

def readPoints(path):
"""Reads points (landmarks) from a text file."""
points = []
with open(path) as file:
for line in file:
x, y = line.split()
points.append((int(x), int(y)))
return points

def writePoints(path, points):
"""Saves the list of points to a text file."""
with open(path, "w") as file:
for (x, y) in points:
file.write(f"{x} {y}\n")

###############################
# Add corner and edge points
###############################
def addBorderPoints(points, width, height):
"""Adds the four corners of the image to the list of points."""
points.append((0, 0))
points.append((width - 1, 0))
points.append((0, height - 1))
points.append((width - 1, height - 1))

def addEdgePoints(points, width, height, step=50):
"""
Adds points along the edges with a 'step' interval.
"""
# Top edge
for x in range(step, width - 1, step):
points.append((x, 0))
# Bottom edge
for x in range(step, width - 1, step):
points.append((x, height - 1))
# Left edge
for y in range(step, height - 1, step):
points.append((0, y))
# Right edge
for y in range(step, height - 1, step):
points.append((width - 1, y))

###############################
# Exclude ORB points inside the face
###############################
def filter_orb_in_face(pts1, pts2, face_rect1, face_rect2, margin=0):
"""
Excludes ORB points that fall inside the facial rectangle.
face_rect is (x, y, w, h).
"""
x1, y1, w1, h1 = face_rect1
x2, y2, w2, h2 = face_rect2
filtered1 = []
filtered2 = []
for (px, py), (qx, qy) in zip(pts1, pts2):
inside1 = (x1 - margin <= px <= x1 + w1 + margin and
y1 - margin <= py <= y1 + h1 + margin)
inside2 = (x2 - margin <= qx <= x2 + w2 + margin and
y2 - margin <= qy <= y2 + h2 + margin)
if not (inside1 or inside2):
filtered1.append((px, py))
filtered2.append((qx, qy))
return filtered1, filtered2

###############################
# Delaunay triangulation and morphing
###############################
def find_index(points, point, eps=1.0):
"""Finds in 'points' a point that is within 'eps' of 'point'."""
for i, p in enumerate(points):
if abs(p[0] - point[0]) < eps and abs(p[1] - point[1]) < eps:
return i
return None

def generateDelaunayTriangles(points, width, height):
"""
Generates a Delaunay triangulation from a list of points within a rectangle (0,0,width,height).
Returns a list of triangles (indices).
"""
rect = (0, 0, width, height)
subdiv = cv2.Subdiv2D(rect)
for p in points:
subdiv.insert(p)
triangleList = subdiv.getTriangleList()
triangles = []
for t in triangleList:
pt1 = (t[0], t[1])
pt2 = (t[2], t[3])
pt3 = (t[4], t[5])
index1 = find_index(points, pt1)
index2 = find_index(points, pt2)
index3 = find_index(points, pt3)
if index1 is not None and index2 is not None and index3 is not None:
triangles.append((index1, index2, index3))
return triangles

def applyAffineTransform(src, srcTri, dstTri, size):
"""Applies an affine transform from srcTri to dstTri on src."""
warpMat = cv2.getAffineTransform(np.float32(srcTri), np.float32(dstTri))
dst = cv2.warpAffine(src, warpMat, (size[0], size[1]), None,
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REFLECT_101)
return dst

def morphTriangle(img1, img2, img, t1, t2, t, alpha):
"""Performs triangle morphing and copies the result into 'img'."""
r1 = cv2.boundingRect(np.float32([t1]))
r2 = cv2.boundingRect(np.float32([t2]))
r = cv2.boundingRect(np.float32([t]))

tRect = []
t1Rect = []
t2Rect = []
for i in range(3):
tRect.append((t[i][0] - r[0], t[i][1] - r[1]))
t1Rect.append((t1[i][0] - r1[0], t1[i][1] - r1[1]))
t2Rect.append((t2[i][0] - r2[0], t2[i][1] - r2[1]))

mask = np.zeros((r[3], r[2], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(tRect), (1.0, 1.0, 1.0), 16, 0)

img1Rect = img1[r1[1]:r1[1]+r1[3], r1[0]:r1[0]+r1[2]]
img2Rect = img2[r2[1]:r2[1]+r2[3], r2[0]:r2[0]+r2[2]]
size = (r[2], r[3])
warpImage1 = applyAffineTransform(img1Rect, t1Rect, tRect, size)
warpImage2 = applyAffineTransform(img2Rect, t2Rect, tRect, size)

imgRect = (1.0 - alpha) * warpImage1 + alpha * warpImage2

existing = img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]]
img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = existing * (1 - mask) + imgRect * mask

###############################
# Main program
###############################
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Global morph with facial landmarks, ORB + RANSAC, and edge points, excluding the facial region from ORB.")
parser.add_argument('--src', required=True, help='Path to the source image (e.g. C:\\image1.jpg)')
parser.add_argument('--dest', required=True, help='Path to the destination image (e.g. C:\\image2.jpg)')
parser.add_argument('--frames', type=int, default=30, help='Number of intermediate frames')
parser.add_argument('--output', required=True, help='Path to the output video (e.g. C:\\output2.mp4)')
parser.add_argument('--predictor', required=True, help='Path to the dlib predictor file (e.g. shape_predictor_68_face_landmarks.dat)')
parser.add_argument('--orbfeatures', type=int, default=500, help='Maximum number of ORB features')
parser.add_argument('--ransac', type=float, default=5.0, help='RANSAC reprojection threshold')
parser.add_argument('--edgestep', type=int, default=50, help='Step size for adding edge points')
parser.add_argument('--marginface', type=int, default=0, help='Margin to exclude ORB points inside the face')
parser.add_argument('--fps', type=int, default=30, help='Output video FPS')
args = parser.parse_args()

# 1) Load images (uint8 for ORB, float32 for morph)
img1_uint8 = cv2.imread(args.src)
img2_uint8 = cv2.imread(args.dest)
if img1_uint8 is None or img2_uint8 is None:
raise Exception("Error loading the images. Check the paths.")

height, width, _ = img1_uint8.shape
img1 = np.float32(img1_uint8)
img2 = np.float32(img2_uint8)

# 2) Detect landmarks and bounding box (remove existing .txt to recalculate)
landmarks_path1 = args.src + '.txt'
landmarks_path2 = args.dest + '.txt'

for path in (landmarks_path1, landmarks_path2):
try:
os.remove(path)
except FileNotFoundError:
# If it doesn't exist, ignore
pass
except Exception as e:
print(f"Warning deleting {path}: {e}")

points1, rect1 = detectLandmarksAndRect(args.src, args.predictor)
writePoints(landmarks_path1, points1)
points2, rect2 = detectLandmarksAndRect(args.dest, args.predictor)
writePoints(landmarks_path2, points2)

# 3) Add corner and edge points
addBorderPoints(points1, width, height)
addEdgePoints(points1, width, height, step=args.edgestep)
addBorderPoints(points2, width, height)
addEdgePoints(points2, width, height, step=args.edgestep)

# 4) ORB and RANSAC for the rest of the image, excluding the facial area
pts1_orb, pts2_orb = detect_orb_features(img1_uint8, img2_uint8, max_features=args.orbfeatures)
pts1_orb_filtered, pts2_orb_filtered = filter_matches_ransac(pts1_orb, pts2_orb, reproj_threshold=args.ransac)
pts1_orb_final, pts2_orb_final = filter_orb_in_face(
pts1_orb_filtered, pts2_orb_filtered,
rect1, rect2, margin=args.marginface
)
for (x, y) in pts1_orb_final:
points1.append((x, y))
for (x, y) in pts2_orb_final:
points2.append((x, y))

if len(points1) != len(points2):
raise Exception("The number of points in points1 and points2 does not match after ORB filtering.")

# 5) Generate average points for triangulation
avgPoints = []
for i in range(len(points1)):
avgPoints.append(((points1[i][0] + points2[i][0]) / 2.0,
(points1[i][1] + points2[i][1]) / 2.0))

# 6) Delaunay triangulation
triangles = generateDelaunayTriangles(avgPoints, width, height)
if not triangles:
raise RuntimeError("No Delaunay triangles generated; check the points.")

# 7) Set up VideoWriter with specified FPS
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = args.fps
video_writer = cv2.VideoWriter(args.output, fourcc, fps, (width, height))

# 8) Generate frames
n_frames = args.frames
for f in range(n_frames + 1):
alpha = f / float(n_frames)
imgMorph = np.zeros_like(img1, dtype=np.float32)

# Interpolate points
interpPoints = []
for i in range(len(points1)):
x = (1 - alpha) * points1[i][0] + alpha * points2[i][0]
y = (1 - alpha) * points1[i][1] + alpha * points2[i][1]
interpPoints.append((x, y))

# Morph each triangle
for (i, j, k) in triangles:
t1 = [points1[i], points1[j], points1[k]]
t2 = [points2[i], points2[j], points2[k]]
t = [interpPoints[i], interpPoints[j], interpPoints[k]]
morphTriangle(img1, img2, imgMorph, t1, t2, t, alpha)

frame_uint8 = np.uint8(imgMorph)
video_writer.write(frame_uint8)
print(f"Frame {f} generated.")

video_writer.release()
try:
cv2.destroyAllWindows()
except Exception:
# If not implemented (headless build), ignore
pass
print("Video successfully generated:", args.output)

ChatGPT dijo:

Para tener prints “coloreados” en la consola de Windows (o en cualquier terminal que soporte ANSI), te recomiendo usar la librería colorama, que evita líos con los escape codes. Así:

Instala colorama

bash

CopiarEditar

pip install colorama

Importa e inicializa en tu script

Añade al principio, justo después de los imports actuales:

python

CopiarEditar

import colorama
from colorama import Fore, Style

colorama.init(autoreset=True)

Usa los colores en tus prints

Por ejemplo, para un mensaje de progreso en verde:

python

CopiarEditar

print(Fore.GREEN + f"Frame {f} generated." + Style.RESET_ALL)

Para advertencias en amarillo:

python

CopiarEditar

print(Fore.YELLOW + f"Warning deleting {path}: {e}" + Style.RESET_ALL)

Para errores o mensajes finales en rojo:

python

CopiarEditar

print(Fore.RED + "Video successfully generated: " + args.output + Style.RESET_ALL)

Fragmento completo adaptado

Solo como ejemplo, aquí se ve tu bucle de frames con prints coloreados:

python

CopiarEditar

import colorama
from colorama import Fore, Style
colorama.init(autoreset=True)

# ... resto de imports y funciones ...

if __name__ == '__main__':
# parser, args, carga de imágenes, etc.

# 8) Generar frames
n_frames = args.frames
for f in range(n_frames + 1):
alpha = f / float(n_frames)
# ... cálculo del morph ...

video_writer.write(frame_uint8)
# Aquí el print en verde:
print(Fore.GREEN + f"Frame {f} generated." + Style.RESET_ALL)

video_writer.release()
try:
cv2.destroyAllWindows()
except Exception:
pass
# Mensaje final en cian, por ejemplo:
print(Fore.CYAN + "Video successfully generated: " + args.output + Style.RESET_ALL)

Nota: gracias a autoreset=True tras cada print vuelves automáticamente al color por defecto, así no tienes que añadir + Style.RESET_ALL si no quieres. También puedes combinar con Back.* para fondos o Style.BRIGHT/DIM para brillo.

Dijiste:

cOMO PONDRIA BIEN ESTA LIENA?
print(f"{GREEN_1}Video successfully generated:{RESET}", {ORANGE_1}args.output{RESET})

ChatGPT dijo:

Pensado durante 6 segundos

En Python la forma más sencilla es meter todo en un solo f-string, así:

python

CopiarEditar

print(f"{GREEN_1}Video successfully generated: {ORANGE_1}{args.output}{RESET}")

Si prefieres dejar los textos en dos parámetros de print, tendrías que convertir también el segundo en otro f-string:

python

CopiarEditar

print(f"{GREEN_1}Video successfully generated:{RESET}",
f"{ORANGE_1}{args.output}{RESET}")

Lo importante es que las llaves sólo van dentro de un f-string, por ejemplo f"{VAR}", y nunca sueltas entre comas.

Herramientas

ChatGPT puede cometer errores. Comprueba la información importante. Consulta Preferencias de cookies.