que poner pasa mas los historias hashtags funcionan editar deja copiar con como comentarios c# image algorithm image-processing aforge

c# - poner - Mejora automática de imágenes escaneadas



no me funcionan los hashtags en instagram 2018 (4)

Convierta su RGB a HSL usando esto:

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue); float hue = color.GetHue(); float saturation = color.GetSaturation(); float lightness = color.GetBrightness();

Ajuste su Saturación y Luminosidad en consecuencia

Convierte HSL a RGB de la siguiente manera:

/// <summary> /// Convert HSV to RGB /// h is from 0-360 /// s,v values are 0-1 /// r,g,b values are 0-255 /// Based upon http://ilab.usc.edu/wiki/index.php/HSV_And_H2SV_Color_Space#HSV_Transformation_C_.2F_C.2B.2B_Code_2 /// </summary> void HsvToRgb(double h, double S, double V, out int r, out int g, out int b) { // ###################################################################### // T. Nathan Mundhenk // [email protected] // C/C++ Macro HSV to RGB double H = h; while (H < 0) { H += 360; }; while (H >= 360) { H -= 360; }; double R, G, B; if (V <= 0) { R = G = B = 0; } else if (S <= 0) { R = G = B = V; } else { double hf = H / 60.0; int i = (int)Math.Floor(hf); double f = hf - i; double pv = V * (1 - S); double qv = V * (1 - S * f); double tv = V * (1 - S * (1 - f)); switch (i) { // Red is the dominant color case 0: R = V; G = tv; B = pv; break; // Green is the dominant color case 1: R = qv; G = V; B = pv; break; case 2: R = pv; G = V; B = tv; break; // Blue is the dominant color case 3: R = pv; G = qv; B = V; break; case 4: R = tv; G = pv; B = V; break; // Red is the dominant color case 5: R = V; G = pv; B = qv; break; // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won''t slow us down at all to put these here. case 6: R = V; G = tv; B = pv; break; case -1: R = V; G = pv; B = qv; break; // The color is not defined, we should throw an error. default: //LFATAL("i Value error in Pixel conversion, Value is %d", i); R = G = B = V; // Just pretend its black/white break; } } r = Clamp((int)(R * 255.0)); g = Clamp((int)(G * 255.0)); b = Clamp((int)(B * 255.0)); } /// <summary> /// Clamp a value to 0-255 /// </summary> int Clamp(int i) { if (i < 0) return 0; if (i > 255) return 255; return i; }

Código original:

Estoy desarrollando una rutina para la mejora automática de diapositivas escaneadas de 35 mm. Estoy buscando un buen algoritmo para aumentar el contraste y eliminar el matiz de color. El algoritmo tendrá que ser completamente automático, ya que habrá miles de imágenes para procesar. Estas son un par de imágenes de muestra directamente del escáner, solo recortadas y reducidas para la web:

Estoy usando la biblioteca AForge.NET y he probado los filtros HistogramEqualization y ContrastStretch . HistogramEqualization es buena para maximizar el contraste local, pero no produce resultados agradables en general. ContrastStretch es mucho mejor, pero como estira el histograma de cada banda de color individualmente, a veces produce un fuerte tono de color:

Para reducir el cambio de color, creé un filtro LevelsLinear utilizando las clases ImageStatistics y LevelsLinear . Utiliza el mismo rango para todas las bandas de color, preservando los colores a expensas de menos contraste.

ImageStatistics stats = new ImageStatistics(image); int min = Math.Min(Math.Min(stats.Red.Min, stats.Green.Min), stats.Blue.Min); int max = Math.Max(Math.Max(stats.Red.Max, stats.Green.Max), stats.Blue.Max); LevelsLinear levelsLinear = new LevelsLinear(); levelsLinear.Input = new IntRange(min, max); Bitmap stretched = levelsLinear.Apply(image);

La imagen sigue siendo bastante azul, así que creé un filtro ColorCorrection que primero calcula la luminancia media de la imagen. A continuación, se calcula un valor de corrección gamma para cada canal de color, de modo que el valor medio de cada canal de color sea igual a la luminancia media. La imagen estirada de contraste uniforme tiene valores medios R=70 G=64 B=93 , siendo la luminancia media (70 + 64 + 93) / 3 = 76 . Los valores gamma se calculan para R=1.09 G=1.18 B=0.80 y la imagen resultante, muy neutral, tiene valores medios de R=76 G=76 B=76 como se esperaba:

Ahora, llegando al problema real ... Supongo que corregir el color medio de la imagen al gris es un poco demasiado drástico y hará que algunas imágenes sean bastante aburridas en apariencia, como la segunda muestra (la primera imagen se estira uniformemente, luego está el mismo color de imagen corregido):

Una forma de realizar la corrección de color manualmente en un programa de edición de fotografías es muestrear el color de un color neutro conocido (blanco / gris / negro) y ajustar el resto de la imagen a eso. Pero como esta rutina debe ser completamente automática, no es una opción.

Supongo que podría agregar una configuración de resistencia a mi filtro ColorCorrection , de modo que una fuerza de 0.5 moverá los valores medios la mitad de la distancia a la luminancia media. Pero, por otro lado, algunas imágenes podrían funcionar mejor sin ninguna corrección de color.

¿Alguna idea para un algoritmo mejor? ¿O algún método para detectar si una imagen tiene un tinte de color o simplemente tiene mucho color, como la segunda muestra?


Necesitaba hacer lo mismo en una gran biblioteca de miniaturas de videos. Quería una solución que fuera conservadora, para que no tuviese que controlar que las miniaturas quedaran completamente destrozadas. Aquí está la solución desordenada y hackeada que utilicé.

Primero utilicé esta clase para calcular la distribución de colores en una imagen. Primero hice uno en el espacio de color HSV, pero encontré que uno basado en escala de grises era mucho más rápido y casi tan bueno:

class GrayHistogram def initialize(filename) @hist = hist(filename) @percentile = {} end def percentile(x) return @percentile[x] if @percentile[x] bin = @hist.find{ |h| h[:count] > x } c = bin[:color] return @percentile[x] ||= c/256.0 end def midpoint (percentile(0.25) + percentile(0.75)) / 2.0 end def spread percentile(0.75) - percentile(0.25) end private def hist(imgFilename) histFilename = "/tmp/gray_hist.txt" safesystem("convert #{imgFilename} -depth 8 -resize 50% -colorspace GRAY /tmp/out.png") safesystem("convert /tmp/out.png -define histogram:unique-colors=true " + " -format /"%c/" histogram:info:- > #{histFilename}") f = File.open(histFilename) lines = f.readlines[0..-2] # the last line is always blank hist = lines.map { |line| { :count => /([0-9]*):/.match(line)[1].to_i, :color => /,([0-9]*),/.match(line)[1].to_i } } f.close tot = 0 cumhist = hist.map do |h| tot += h[:count] {:count=>tot, :color=>h[:color]} end tot = tot.to_f cumhist.each { |h| h[:count] = h[:count] / tot } safesystem("rm /tmp/out.png #{histFilename}") return cumhist end end

Luego creé esta clase para usar el histograma para descubrir cómo corregir una imagen:

def safesystem(str) out = `#{str}` if $? != 0 puts "shell command failed:" puts "/tcmd: #{str}" puts "/treturn code: #{$?}" puts "/toutput: #{out}" raise end end def generateHist(thumb, hist) safesystem("convert #{thumb} histogram:hist.jpg && mv hist.jpg #{hist}") end class ImgCorrector def initialize(filename) @filename = filename @grayHist = GrayHistogram.new(filename) end def flawClass if !@flawClass gapLeft = (@grayHist.percentile(0.10) > 0.13) || (@grayHist.percentile(0.25) > 0.30) gapRight = (@grayHist.percentile(0.75) < 0.60) || (@grayHist.percentile(0.90) < 0.80) return (@flawClass="low" ) if (!gapLeft && gapRight) return (@flawClass="high" ) if ( gapLeft && !gapRight) return (@flawClass="narrow") if ( gapLeft && gapRight) return (@flawClass="fine" ) end return @flawClass end def percentileSummary [ @grayHist.percentile(0.10), @grayHist.percentile(0.25), @grayHist.percentile(0.75), @grayHist.percentile(0.90) ].map{ |x| (((x*100.0*10.0).round)/10.0).to_s }.join('', '') + "<br />" + "spread: " + @grayHist.spread.to_s end def writeCorrected(filenameOut) if flawClass=="fine" safesystem("cp #{@filename} #{filenameOut}") return end # spread out the histogram, centered at the midpoint midpt = 100.0*@grayHist.midpoint # map the histogram''s spread to a sigmoidal concept (linearly) minSpread = 0.10 maxSpread = 0.60 minS = 1.0 maxS = case flawClass when "low" then 5.0 when "high" then 5.0 when "narrow" then 6.0 end s = ((1.0 - [[(@grayHist.spread - minSpread)/(maxSpread-minSpread), 0.0].max, 1.0].min) * (maxS - minS)) + minS #puts "s: #{s}" safesystem("convert #{@filename} -sigmoidal-contrast #{s},#{midpt}% #{filenameOut}") end end

Lo ejecuté así:

origThumbs = `find thumbs | grep jpg`.split("/n") origThumbs.each do |origThumb| newThumb = origThumb.gsub(/thumb/, "newthumb") imgCorrector = ImgCorrector.new(origThumb) imgCorrector.writeCorrected(newThumb) end


Para evitar cambiar el color de su imagen al estirar el contraste, conviértalo primero a un espacio de color HSV / HSL. Luego, aplique un estiramiento de restricción regular en el canal L o V pero no en los canales H o S de chagen.


  • traducido a hsv
  • La capa V se corrige al escalar valores del rango (mínimo, máximo) al rango (0,255)
  • ensamblado de nuevo a rgb
  • corrigiendo las capas de resultado R, G, B por la misma idea que la capa V en el segundo paso

no hay un código de aforge.net, porque procesado por el código prototipo php, pero afaik no hay ningún problema para hacer eso con aforge.net. los resultados son: