2013-10-14 15 views
9

Sto usando OpenCV per elaborare alcune immagini e uno dei primi passi che devo eseguire è aumentare il contrasto dell'immagine su un'immagine a colori. Il metodo più veloce che ho trovato finora utilizza questo codice (dove np è l'importazione NumPy) per moltiplicare e aggiungere come suggerito nella original C-based cv1 docs:Qual è il modo più rapido per aumentare il contrasto dell'immagine a colori con OpenCV in python (cv2)?

if (self.array_alpha is None): 
     self.array_alpha = np.array([1.25]) 
     self.array_beta = np.array([-100.0]) 

    # add a beta value to every pixel 
    cv2.add(new_img, self.array_beta, new_img)      

    # multiply every pixel value by alpha 
    cv2.multiply(new_img, self.array_alpha, new_img) 

Esiste un modo più veloce per fare questo in Python? Ho provato a usare moltiplicare scalare di Numpy, ma la performance è in realtà peggiore. Ho anche provato a utilizzare cv2.convertScaleAbs (i documenti OpenCV suggerivano di usare convertTo, ma cv2 sembra mancare un'interfaccia per questa funzione), ma ancora una volta le prestazioni erano peggiori nei test.

+0

Sarebbe già più veloce. È solo un'aggiunta e una moltiplicazione. –

+0

Le operazioni di addizione e moltiplicazione possono essere eseguite contemporaneamente per ottenere effetti interessanti. Fondamentalmente, ogni pixel può essere trasformato come 'X = aY + b' dove' a' e 'b' sono scalari. Questa è una trasformazione lineare.Ho mostrato una trasformazione quadratica nelle risposte che produce risultati molto più interessanti;) – samkhan13

risposta

15

L'aritmetica semplice negli array numpy è la più veloce, come ha commentato Abid Rahaman K.

Usa questa immagine per esempio: http://i.imgur.com/Yjo276D.png

Ecco un po 'di elaborazione delle immagini che assomiglia luminosità/contrasto manipolazione:

''' 
Simple and fast image transforms to mimic: 
- brightness 
- contrast 
- erosion 
- dilation 
''' 

import cv2 
from pylab import array, plot, show, axis, arange, figure, uint8 

# Image data 
image = cv2.imread('imgur.png',0) # load as 1-channel 8bit grayscale 
cv2.imshow('image',image) 
maxIntensity = 255.0 # depends on dtype of image data 
x = arange(maxIntensity) 

# Parameters for manipulating image data 
phi = 1 
theta = 1 

# Increase intensity such that 
# dark pixels become much brighter, 
# bright pixels become slightly bright 
newImage0 = (maxIntensity/phi)*(image/(maxIntensity/theta))**0.5 
newImage0 = array(newImage0,dtype=uint8) 

cv2.imshow('newImage0',newImage0) 
cv2.imwrite('newImage0.jpg',newImage0) 

y = (maxIntensity/phi)*(x/(maxIntensity/theta))**0.5 

# Decrease intensity such that 
# dark pixels become much darker, 
# bright pixels become slightly dark 
newImage1 = (maxIntensity/phi)*(image/(maxIntensity/theta))**2 
newImage1 = array(newImage1,dtype=uint8) 

cv2.imshow('newImage1',newImage1) 

z = (maxIntensity/phi)*(x/(maxIntensity/theta))**2 

# Plot the figures 
figure() 
plot(x,y,'r-') # Increased brightness 
plot(x,x,'k:') # Original image 
plot(x,z, 'b-') # Decreased brightness 
#axis('off') 
axis('tight') 
show() 

# Close figure window and click on other window 
# Then press any keyboard key to close all windows 
closeWindow = -1 
while closeWindow<0: 
    closeWindow = cv2.waitKey(1) 
cv2.destroyAllWindows() 

immagine originale in scala di grigi:

enter image description here

Immagine luminosa che sembra dilatata:

enter image description here

immagine Darkened che sembra essere eroso, affilato, con maggior contrasto:

enter image description here

Come le intensità dei pixel si stanno trasformando:

enter image description here

Se gioca con i valori di phi e theta puoi diventare davvero interessante tcomes. Puoi anche implementare questo trucco per i dati delle immagini multicanale.

--- EDIT ---

uno sguardo ai concetti di 'livelli' e 'curve' su this youtube video che mostrano l'editing di immagini in Photoshop. L'equazione per la trasformazione lineare crea la stessa quantità di "livello" di cambiamento su ogni pixel. Se si scrive un'equazione che può discriminare tra tipi di pixel (ad esempio quelli che sono già di un certo valore), è possibile modificare i pixel in base alla "curva" descritta da tale equazione.

+0

Cosa succede se ho bisogno di compilare entrambe le funzioni, aumentando la luminosità dei pixel scuri e diminuendo la luminosità di Over pixel luminosi allo stesso tempo. Possiamo raggiungere questo comportamento. – ZdaR

+0

Ho provato ma non ho ottenuto i risultati desiderati, nessun suggerimento – ZdaR

+0

@Anmol_uppal come ho detto nella parte --- EDIT ---, dovrai trovare quell'equazione che lo fa. il metodo più semplice che posso pensare è usare la funzione cv2.inrange() per modificare i pixel all'interno di un limite inferiore e superiore. potresti semplicemente dover chiamare cv2.inrange() due volte per due diverse condizioni limite. – samkhan13

5

provare questo codice:

import cv2 

img = cv2.imread('sunset.jpg', 1) 
cv2.imshow("Original image",img) 

# CLAHE (Contrast Limited Adaptive Histogram Equalization) 
clahe = cv2.createCLAHE(clipLimit=3., tileGridSize=(8,8)) 

lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) # convert from BGR to LAB color space 
l, a, b = cv2.split(lab) # split on 3 different channels 

l2 = clahe.apply(l) # apply CLAHE to the L-channel 

lab = cv2.merge((l2,a,b)) # merge channels 
img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) # convert from LAB to BGR 
cv2.imshow('Increased contrast', img2) 
#cv2.imwrite('sunset_modified.jpg', img2) 

cv2.waitKey(0) 
cv2.destroyAllWindows() 

tramonto prima: enter image description here Tramonto dopo un aumento di contrasto: enter image description here

+1

L'OP chiede l'aumento del contrasto *** *** più veloce, per loro una trasformazione lineare non è abbastanza veloce! come si confronta la tua soluzione proposta - in senso orario - con la procedura non abbastanza veloce nell'OP? – gboffi

+0

@gboffi - Sì, "il modo più veloce" ... Ero così premuroso nel realizzare immagini a colori più nitide, che l'essenza della domanda non mi è venuta in mente :-). Come so che NumPy ha una velocità di linguaggio C, perché è scritto in C. È più veloce di C? Sì, è un montatore :-). Non penso che ci sia un algoritmo più veloce della trasformazione lineare della matrice 2D. Quindi se OP esegue la trasformazione lineare della matrice 2D su Assembler sarà più veloce del linguaggio C (o NumPy che è scritto in C). Non penso che CLAHE sia più veloce della trasformazione lineare NumPy, perché è un algoritmo più complesso. –

+0

Questo codice ha lo svantaggio di aumentare il contrasto del canale di luminanza ma lascia invariati i canali di colore. Quindi l'immagine del risultato ha ridotto il contrasto del colore. Le tue foto non sono il miglior esempio. Quando provi questo con altre foto che hanno più colori e meno contrasto noterai che questo codice non produce i risultati ottimali. – Elmue

Problemi correlati