Cambiar el tamaño de todas las imágenes almacenadas en la matriz

Nawr C:

Yo imágenes almacenadas leído a través cv2.imreadde una matriz masks. La forma de la matriz es (10, 5248, 7936, 3) (10 images, image height, image width, 3 channels).

Ahora estoy tratando de copiar esta matriz, pero con cada imagen redimensionada a los valores monitor_hy monitor_w. Aquí es lo que tengo:

resized_masks = np.empty([masks.shape[0], monitor_h, monitor_w, masks.shape[3]])

for i in range(masks.shape[0]):
    resized_masks[i] = cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h))

Pero las imágenes que recibo de cv2.imshowson en blanco y negro. Algo debe haber sucedido con los canales. ¿Alguna pista?

El físico loco:

Para entender por qué sus imágenes están saliendo blanco y negro, vamos a paso a través del código.

resized_masks = np.empty([masks.shape[0], monitor_h, monitor_w, masks.shape[3]])

Esta línea crea una matriz de tipo np.floatpor defecto.

resized_masks[i] = cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h))

Esta línea asigna el resultado de cv2.resizeque una rebanada de resized_masks.

Sus imágenes originales, y por lo tanto el resultado de cv2.resize, presumiblemente, son de tipo np.uint8. La asignación arroja los valores en floats para ponerlos en el búfer. El elenco está bien en sí mismo: 5conversos a 5.0, 255convertidos a 255.0. El problema es que floatlos valores se interpretan como siendo recortado a la gama [0.0, 1.0], no [0.0, 255.0]. Por lo tanto, se termina con imágenes que son efectivamente todos los ceros y unos, a pesar de que contienen lo que parece a los valores correctos.

Puede comprobar que los valores son correctos, mostrando

resized_masks.astype(masks.dtype)

Esta no es una solución real. La verdadera solución es comenzar con el tipo de salida correcta:

resized_masks = np.empty((masks.shape[0], monitor_h, monitor_w, masks.shape[3]), dtype=masks.dtype)

Tenga en cuenta que es convencional usar tuplas para las formas y no constituyen listas, pero no importa funcionalmente.

Ahora vamos a ver por qué su parche funcionó.

resized_masks = list(resized_masks)

Esto crea una lista de Python de referencias a cada sub-serie. Puesto que usted está realmente cortado, que todavía se apuntan a una memoria intermedia contigua bajo el capó, pero lo importante es que cada uno resized_masks[i]es una referencia por separado, no una rebanada en el mismo objeto de matriz.

resized_masks[i] = list(cv2.resize(np.copy(masks[i]), (monitor_w, monitor_h)))

Desde resized_maskses una lista que contiene referencias, esto es ahora asignando el resultado de cv2.resizeque el ielemento de la lista XX, no asignar el contenido en una rebanada de tamaño apropiado. No es necesario el listenvoltorio aquí, ya que introduce una dimensión innecesaria.

resized_masks = np.asarray(resized_masks)

Esto sólo se recombina la lista en una matriz, ya que todos los elementos son del tamaño adecuado (aunque verá una dimensión unidad adicional, como se mencionó anteriormente). Como se puede imaginar esta solución es extremadamente ineficiente. En la parte superior del hecho de que usted va hacia y desde las listas y la asignación de múltiples memorias intermedias innecesarias, también se va a desechar el original np.emptymatriz sin usarlo.

El parche es más o menos lo mismo que hacer

resized_masks = np.array([cv2.resize(np.copy(mask), (monitor_w, monitor_h)) for mask in masks])

No recomiendo hacerlo así.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=320423&siteId=1
Recomendado
Clasificación