Skip to content

Leggere e salvare file immagine con Python e OpenCV (imread, imwrite)

Python

In Python e OpenCV, puoi leggere (caricare) e scrivere (salvare) file di immagine con cv2.imread() e cv2.imwrite(). Le immagini vengono lette come array NumPy ndarray.

In questo articolo vengono descritti i seguenti contenuti.

  • Leggere e scrivere immagini a colori (BGR)
    • Leggi un file immagine con cv2.imread()
    • Scrivi ndarray come file immagine con cv2.imwrite()
  • Leggere e scrivere immagini in scala di grigi
    • Leggi un file immagine con cv2.imread()
    • Scrivi ndarray come file immagine con cv2.imwrite()
  • Nota su cv2.imread()
    • cv2.imread() non genera un’eccezione
    • Libreria JPEG
  • Se le immagini non possono essere lette con cv2.imread()
    • Controlla la directory corrente
    • Formati supportati per cv2.imread()

È anche possibile leggere i file di immagine come ndarray usando Pillow invece di OpenCV.

L’immagine seguente viene utilizzata come esempio.

lena

Leggere e scrivere immagini a colori (BGR)

Leggi un file immagine con cv2.imread()

I file di immagine a colori vengono letti come una matrice 3D di riga (altezza) x colonna (larghezza) x colore (3).

import cv2

im = cv2.imread('data/src/lena.jpg')

print(type(im))
# 

print(im.shape)
# (225, 400, 3)

print(im.dtype)
# uint8

Si noti che l’ordine dei colori è BGR anziché RGB. Ad esempio, imposta 0 (SI: blu) e 1 (SOL: verde) su 0 (nero).

lena rossa

Se desideri aspirare BGR e RGB, fai riferimento al seguente articolo.

Scrivi ndarray come file immagine con cv2.imwrite()

Per salvare ndarray come file immagine, impostare il percorso del file e l’oggetto ndarray su cv2.imwrite().

Il formato del file immagine viene determinato automaticamente dall’estensione del percorso del file. Se è .jpg, viene salvato come JPEG e se è .png, viene salvato come PNG.

cv2.imwrite('data/dst/lena_opencv_red.jpg', im)

lena rossa

È possibile specificare parametri specifici del formato per il terzo parametro. Specificare con un elenco come [paramId_1, paramValue_1, paramId_2, paramValue_2, …].

Per l’ID parametro (flag), fare riferimento al documento ufficiale di seguito.

Ad esempio, la qualità di JPEG è specificata da cv2.IMWRITE_JPEG_QUALITY. 0 è il più basso e 100 è il più alto, il valore predefinito è 95.

Se salvato come 50:

cv2.imwrite('data/dst/lena_opencv_red_low.jpg', im, [cv2.IMWRITE_JPEG_QUALITY, 50])

lena rossa di bassa qualità

Se salvato come 100:

cv2.imwrite('data/dst/lena_opencv_red_high.jpg', im, [cv2.IMWRITE_JPEG_QUALITY, 100])

lena rossa di alta qualità

Si noti che JPEG è una compressione con perdita di dati, quindi anche se è la qualità massima 100, quando l’immagine salvata viene ricaricata, si verifica una differenza il valore del pixel originale. Se vuoi salvare l’immagine originale così com’è, salvala come PNG o BMP.

Leggere e scrivere immagini in scala di grigi

Leggi un file immagine con cv2.imread()

Passando cv2.IMREAD_GREYSCALE come secondo argomento di cv2.imread(), un file immagine a colori può essere letto in scala di grigi (bianco e nero). Poiché cv2.IMREAD_GREYSCALE è equivalente a 0, anche passare 0 va bene.

È per utile i bordi e altre situazioni in cui non sono richieste informazioni sul colore.

In questo caso, l’immagine viene letta come narray 2D di riga (altezza) x colonna (larghezza).

im_gray = cv2.imread('data/src/lena.jpg', cv2.IMREAD_GRAYSCALE)
# im_gray = cv2.imread('data/src/lena.jpg', 0)

print(type(im_gray))
# 

print(im_gray.shape)
# (225, 400)

print(im_gray.dtype)
# uint8

Puoi leggere il file immagine come colore e convertirlo in scala di grigi con cv2.cvtColor() e cv2.COLOR_BGR2GRAY.

Poiché cv2.IMREAD_GRAYSCALE con cv2.imread() esegue conversioni dipendenti dal codec anziché conversioni implementate da OpenCV, ottenere risultati diversi su piattaforme diverse. cv2.cvtColor() con cv2.COLOR_BGR2GRAY è più sicuro da usare se si desidera gestire rigorosamente i valori dei pixel.

Scrivi ndarray come file immagine con cv2.imwrite()

Se come argomento di cv2.imwrite() viene specificato il narray 2D di riga(altezza) x colonna(larghezza), viene salvato come file immagine in scala di grigi.

cv2.imwrite('data/dst/lena_opencv_gray.jpg', im_gray)

lena grigio

Se vuoi salvare un’immagine a colori (3D ndarray) come file immagine in scala di grigi, convertirla in scala di grigi con cv2.cvtColor() e cv2.COLOR_BGR2GRAY.

Se salvi 2D ndarray in un file e lo leggi di nuovo con cv2.imread(), verrà letto come 3D ndarray in cui ogni colore ha lo stesso valore.

Non si legge automaticamente come una matrice bidimensionale.

im_gray_read = cv2.imread('data/dst/lena_opencv_gray.jpg')

print(im_gray_read.shape)
# (225, 400, 3)

import numpy as np

print(np.array_equal(im_gray_read[:, :, 0], im_gray_read[:, :, 1]))
# True

print(np.array_equal(im_gray_read[:, :, 1], im_gray_read[:, :, 2]))
# True

Nota su cv2.imread()

cv2.imread() non genera un’eccezione

Anche se viene specificato un percorso inesistente, cv2.imread() non genera un’eccezione e restituisce None. Verrà generato un errore quando un utente esegue alcune operazioni presupponendo che venga letto come ndarray.

im = cv2.imread('xxxxxxx')

print(im)
# None

# print(im.shape)
# AttributeError: 'NoneType' object has no attribute 'shape'

Anche se il file esiste, viene restituito None se OpenCV non lo supporta.

im = cv2.imread('data/src/sample.csv')

print(im)
# None

Poiché Nessuno è considerato Falso, è possibile verificare se l’immagine è stata caricata correttamente come segue.

im = cv2.imread('xxxxxxx')

if im:
    print('Image is read.')
else:
    print('Image is not read.')
# Image is not read.
im = cv2.imread('xxxxxxx')

if not im:
    print('Image is not read.')
else:
    print('Image is read.')
# Image is not read.

Libreria JPEG

Come puoi vedere nel problema di GitHub di seguito, la libreria utilizzata per elaborare i JPEG dipende dalla versione di OpenCV, dalla piattaforma, ecc. Pertanto, anche se viene letto lo stesso file, potrebbero esserci differenze nei valori se l’ambiente è diverso.

La lettura di immagini JPEG non è un’operazione bit-esatta. Dipende dalla libreria utilizzata (libjpeg/libjpeg-turbo) e/o dalle versioni, dalle piattaforme (x86/ARM), dalle opzioni del compilatore.
imread e imwrite causano differenze nei pixel dell’immagine · Problema n. 10887 · opencv/opencv

Se le immagini non possono essere lette con cv2.imread()

Controlla la directory corrente

Come la funzione integrata open(), con cv2.imread() e cv2.imwrite(), puoi specificare il percorso di un file con uno dei seguenti metodi:

  • Percorso relativo dalla directory corrente
  • Percorso assoluto

Se il file dovrebbe essere presente ma non può essere letto, è spesso a causa di un semplice errore che la directory corrente è diversa da quella prevista.

Puoi controllare la directory corrente con os.getcwd().

Formati supportati per cv2.imread()

Ovviamente non è possibile leggere file immagine in formati non supportati da OpenCV.

I seguenti formati sono supportati da cv2.imread() di OpenCV 4.2.0. Vedi anche le note al link.

  • Bitmap di Windows – .bmp, .dib (sempre supportati)
  • File JPEG – .jpeg, .jpg, *.jpe (vedi la sezione Note)
  • File JPEG 2000 – *.jp2 (vedi la sezione Note)
  • Portable Network Graphics – *.png (vedi la sezione Note)
  • WebP – *.webp (vedi la sezione Note)
  • Formato immagine portatile – .pbm, .pgm, .ppm .pxm, *.pnm (sempre supportato)
  • File PFM – *.pfm (vedi la sezione Note)
  • Raster Sun – .sr, .ras (sempre supportati)
  • File TIFF – .tiff, .tif (vedi la sezione Note)
  • File immagine OpenEXR – *.exr (vedi la sezione Note)
  • Radiance HDR – .hdr, .pic (sempre supportato)
  • Dati geospaziali raster e vettoriali supportati da GDAL (vedi la sezione Note)
    OpenCV: Lettura e scrittura di file immagine

Vedi sotto per altre versioni.

Puoi controllare le informazioni sulle librerie e così via nella sezione Media I/O di cv2.getBuildInformation().

cv2.imread() controlla il formato di un file dal suo contenuto, non dalla sua estensione. Se il file non può essere letto, controlla se il file può essere letto da un’altra applicazione (controlla se il file non è danneggiato).

La funzione determina il tipo di immagine dal contenuto, non dall’estensione del file.
OpenCV: lettura e scrittura di file immagine