Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

234
Vistas
¿Cómo obtener un histograma suave después de escalar la imagen?

Estoy tratando de escalar linealmente una imagen para que se use todo el rango de escala de grises. Esto es para mejorar la iluminación de la toma. Sin embargo, al trazar el histograma, no sé cómo obtener el histograma escalado para que sea más suave, por lo que es una curva como se aspira a contenedores discretos. Cualquier consejo o punto sería muy apreciado.

 import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread(r'/Users/harold/Documents/Academia/Nottingham Uni/Year 4/ImageProcessing/Imaging_Task_Sheet/PointImage.jpeg', cv.IMREAD_GRAYSCALE) img_s = img/255 img_s = img_s / np.max(img_s) img_s = img_s*255 histogram = cv.calcHist([img], [0], None, [256], [0, 256]) histogram1 = cv.calcHist([img_s.astype('uint8')], [0], None, [256], [0, 256]) plt.figure() plt.title("Grayscale Histogram") plt.xlabel("grayscale value") plt.ylabel("pixels") plt.plot(histogram, label='Original Image') # <- or here plt.plot(histogram1, label='Equalised Image') # <- or here

El histograma producido es:

ingrese la descripción de la imagen aquí

Que es de esta imagen:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
4 Respuestas
Responde la pregunta

0

No estoy seguro de si esto es posible si está escalando linealmente la imagen. Sin embargo, puede probar la ecualización de histograma adaptativo limitado de contraste de OpenCV:

 import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread('3NKTJ.jpg', cv.IMREAD_GRAYSCALE) img_clahe = img.copy() img_clahe = img_clahe/np.max(img_clahe) img_clahe = (255*img_clahe).astype(np.uint8) clahe = cv.createCLAHE(clipLimit=5, tileGridSize=(3,3)) img_clahe = clahe.apply(img_clahe) img_s = img/255 img_s = img_s / np.max(img_s) img_s = img_s*255 histogram = cv.calcHist([img], [0], None, [256], [0, 256]) histogram1 = cv.calcHist([img_s.astype('uint8')], [0], None, [256], [0, 256]) histogram2 = cv.calcHist([img_clahe.astype('uint8')], [0], None, [256], [0, 256]) plt.figure(dpi=100) plt.title("Grayscale Histogram") plt.xlabel("grayscale value") plt.ylabel("pixels") plt.plot(histogram, label='Original Image') # <- or here plt.plot(histogram1, label='Equalised Image') # <- or here plt.plot(histogram2, label='CLAHE Image') plt.legend() plt.show()

ingrese la descripción de la imagen aquí

Puede jugar con clipLimit y tileGridSize para que la imagen tenga el aspecto que desea. Los valores predeterminados son 40.0 y (8, 8) .

over 4 years ago · Santiago Trujillo Denunciar

0

Estoy tratando de escalar linealmente una imagen para que se use todo el rango de escala de grises

Para aumentar la dinámica de la imagen, existe un método común de procesamiento de imágenes llamado "Ecualización de histograma" (ver: cv.equalizeHist() , doc )

Para obtener un mejor resultado, debe eliminar los valores extremos de la imagen, para eliminar la sub/sobreexposición.

Para ello, sobre la imagen ecualizada:

  • calcular la suma acumulada del histograma
  • encuentre la primera intensidad menor que la rate y la primera mayor que 1-rate
  • recorte todas las intensidades de imagen a esos 2 valores.

Aquí hay un código de muestra:

 def equalize_hist(data: np.ndarray, rate: float) -> np.ndarray: data = cv.equalizeHist(data.astype(np.uint8)) hist = np.cumsum(np.histogram(data, 255)[0]) lowest_value = np.where((rate * hist[-1]) <= hist)[0][0] highest_value = np.where(((1 - rate) * hist[-1]) >= hist)[0][-1] sdata[self.data < lowest_value] = lowest_value data[self.data > highest_value] = highest_value return data

Un valor común para la rate es 0,05. A medida que aumenta la velocidad, aumenta la dinámica de la imagen, pero pierde información. No puede aumentar la rate encima de 0,5.

over 4 years ago · Santiago Trujillo Denunciar

0

Deberías leer sobre la corrección gamma :

usando el código de esta respuesta que usa una forma automática de calcular el valor gamma, obtienes los siguientes resultados:

Método 1:

ingrese la descripción de la imagen aquí

Método2:

ingrese la descripción de la imagen aquí

Y el histograma de la imagen corregida (método 2) se ve así:

ingrese la descripción de la imagen aquí

** Edit2: ** O podría usar un método lineal para cambiar la escala de cada canal entre 0 y 255. Usando este código:

 def apply_white_balance_single_channel(img, low_ratio=0.001, high_ratio=0.001): hist_size = 256 hist = cv2.calcHist([img], [0], None, [hist_size], [0,hist_size]) acc = np.cumsum(hist) low_limit = low_ratio * acc[-1] high_limit = high_ratio * acc[-1] min_gray = 0 while acc[min_gray] < low_limit and min_gray + 1 < hist_size: min_gray += 1 max_gray = hist_size - 1 while acc[max_gray] >= acc[-1] - high_limit and max_gray > min_gray: max_gray -= 1 input_range = max_gray - min_gray alpha = (hist_size - 1) / input_range beta = -min_gray * alpha return (alpha * img + beta).clip(0,255).astype(np.uint8) def apply_white_balance_multi_channel(img, low_ratio=0.001, high_ratio=0.001): channels = cv2.split(img) return cv2.merge([apply_white_balance_single_channel(ch, low_ratio, high_ratio) for ch in channels])

Lo que da el siguiente resultado:

Imagen reescalada:

ingrese la descripción de la imagen aquí

El histograma:

ingrese la descripción de la imagen aquí

Editar3

O podría usar una versión más simple para hacer el cambio de escala lineal usando una simple normalización min-max:

 def apply_white_balance_multi_channel_min_max(img): channels = cv2.split(img) return cv2.merge([cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX) for ch in channels])
over 4 years ago · Santiago Trujillo Denunciar

0

Creo que lo que tienes en mente es una curva spline que pasa por tus puntos. Aquí está cómo hacerlo:

 import cv2 as cv import numpy as np import matplotlib.pyplot as plt from scipy import interpolate img = cv.imread(r'3NKTJ.jpg', cv.IMREAD_GRAYSCALE) img_s = img/255 img_s = img_s / np.max(img_s) img_s = img_s*255 histogram = cv.calcHist([img], [0], None, [256], [0, 256]) histogram1 = cv.calcHist([img_s.astype('uint8')], [0], None, [256], [0, 256]) x=np.linspace(0,len(histogram1),len(histogram1)) # x: 0 --> 255 with step=1 X=np.where(histogram1>0)[0] # extract bins with non-zero histogram1 values Y=histogram1[X] # the corresponding Y values F=interpolate.splrep(X, Y) # spline representation of (X,Y) Ynew = interpolate.splev(x, F) # calculate interpolated Ynew plt.figure() plt.title("Grayscale Histogram") plt.xlabel("grayscale value") plt.ylabel("pixels") plt.plot(histogram, label='Original Image') # <- or here plt.plot(histogram1, label='Equalised Image') # <- or here plt.plot(x,Ynew, label='spline interpolation of Equalised Image')

A continuación, el resultado: ingrese la descripción de la imagen aquí

Saludos, Stéphane

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda