c# - d7500 - nikon d7200
Algoritmos de cámara digital (3)
Estoy trabajando en un dispositivo de video simple y me gustaría presentar algunas características geniales de la cámara. Entre todos me gustaría presentar
- Indicador de enfoque
- Enfoque automático
- Exposición automática (estimación ideal del tiempo de exposición)
En este momento estoy buscando algunos ejemplos, cómo se pueden implementar estas características. ¿Tienes algún enlace útil?
EDITAR: Ok, usaré una cámara CCD estándar, que puede proporcionar ~ 20fps en ~ 1MPix de resolución. Estoy planeando escribirlo en C #, en caso de problemas de rendimiento, usaré C ++. Tendré lente + cámara CCD + motor.
EDITAR: me gustaría ver una descripción más detallada del algoritmo. Estoy seguro de que algunos tienen que ser enseñados en cursos universitarios, pero tengo problemas para encontrar algunos. Para el indicador de enfoque, probé un enfoque primitivo, pero en algunos casos falló.
int verticalPoints = 0, horizontalPoints = 0;
///Calculate the vertical differences
for (int x = 0; x < toAnalyze.Width; x++)
{
for (int y = 1; y < toAnalyze.Height; y++)
{
byte* pixel = (byte*)data.Scan0 + y * stride + x;
verticalDiff += Math.Abs(*pixel - *(pixel - stride));;
}
}
verticalDiff /= toAnalyze.Width * (toAnalyze.Height-1);
///Calculate horizontal differences
for (int y = 0; y < toAnalyze.Height; y++)
{
for (int x = 1; x < toAnalyze.Width; x++)
{
byte* pixel = (byte*)data.Scan0 + y * stride + x;
horizontalDiff += Math.Abs(*pixel - *(pixel - 1));
}
}
horizontalDiff /= (toAnalyze.Width-1) * toAnalyze.Height;
///And return the average value
return(verticalDiff + horizontalDiff) / 2;
Gracias
Comenzando desde el final, por así decirlo:
La exposición automática es bastante simple: mida el nivel de luz y calcule cuánto tiempo de exposición se necesita para que la luz promedio produzca ~ 15-18% de nivel de gris. Hay muchos intentos de mejorar eso (generalmente midiendo una cantidad de secciones de la imagen por separado y procesando esos resultados), pero ese es el punto de partida.
Hay dos tipos diferentes de autofocus. La mayoría de las cámaras de video usan una basada en la detección del contraste: observe la entrada del sensor y cuando las diferencias entre los píxeles adyacentes se maximicen, considere que está "enfocado".
El enfoque automático de detección de contraste hace que sea un poco difícil hacer una indicación de enfoque, en particular, nunca se sabe realmente cuándo se ha logrado el máximo contraste hasta que el contraste comienza a caer nuevamente. Cuando haces enfoque automático, enfocas hasta que ves un pico y luego ves que empieza a caer nuevamente, y luego lo vuelves a llevar a donde estaba más alto. Para el enfoque manual con un indicador, no puede reconocer el contraste máximo hasta que comienza a caer nuevamente. El usuario tendría que seguir aproximadamente el mismo patrón, pasar el mejor enfoque y luego volver al óptimo.
Alternativamente, puede usar la detección de fase. Esto utiliza la alineación de las "imágenes" que pasa por dos prismas, al igual que los visores de imágenes divididas que se utilizaron en muchas (¿la mayoría?) SLR antes de que se utilizara el enfoque automático.
El AForge.net tiene AForge.net para hacer procesamiento de imágenes, incluidos detección de bordes y filtros de convolución. Otra biblioteca (más grande) que quizás quiera mirar es OpenCV pero solo tiene wrappers para .net, donde como AForge está escrito en c # directamente
Solo para informarte. Estoy trabajando en un software profesional de cámara digital forense de 5 megapíxeles en WPF . En DotNet no C ++. Hay algunos problemas de threading para saber pero funciona perfectamente rápido. Más rendimiento porque se usa GPU.
Jerry hizo un buen trabajo con su respuesta. La detección de enfoque es "detección de contraste en función del tiempo / fotogramas". La lógica es simple, para mantenerlo funcionando no es fácil. Detección de enfoque automático
Para verificar el tiempo de exposición, es fácil si ha creado el histograma de la imagen. Histograma de imagen En cualquier caso, debe hacerlo para
- Canal rojo
- Canal verde
- Canal azul
- Ganancia
- Tiempo de exposición
Esta mezcla lo hace un poco más complicado porque también puede usar canales de ganancia de color para aumentar el brillo de la imagen. Imagen RGB digital . La luminancia puede tener el mismo resultado que con el tiempo de "Ganancia" y "Exposición".
Si calcula el tiempo de exposición de forma automática, tenga en cuenta que necesita un marco para calcularlo y un tiempo de exposición más pequeño a medida que obtenga más cuadros. Eso significa que, si desea tener un buen algoritmo, siempre trate de tener un tiempo de exposición muy pequeño y aumentarlo lentamente. No use un algoritmo lineal en el que disminuya el valor lentamente.
También hay más métodos para cámaras digitales como Pixel Binning Pixel Binning para aumentar la velocidad de fotogramas para obtener resultados de enfoque rápido.
Aquí hay una muestra de cómo el enfoque puede funcionar para generar una imagen de intensidad de enfoque:
Private Sub GetFocusValue(ByRef C1 As Color, ByVal LCol1 As List(Of Color), ByVal LCol2 As List(Of Color), ByVal AmplifierPercent As Single)
Dim MaxDiff1 As Integer = 0
Dim MaxDiff2 As Integer = 0
Dim Factor As Single = 0
Dim D As Integer
Dim LR1 As New List(Of Integer)
Dim LR2 As New List(Of Integer)
Dim LG1 As New List(Of Integer)
Dim LG2 As New List(Of Integer)
Dim LB1 As New List(Of Integer)
Dim LB2 As New List(Of Integer)
For Each C As Color In LCol1
LR1.Add(C.R)
LG1.Add(C.G)
LB1.Add(C.B)
Next
For Each C As Color In LCol2
LR2.Add(C.R)
LG2.Add(C.G)
LB2.Add(C.B)
Next
MaxDiff1 = Me.GetMaxDiff(LR1)
MaxDiff1 = Math.Max(MaxDiff1, Me.GetMaxDiff(LG1))
MaxDiff1 = Math.Max(MaxDiff1, Me.GetMaxDiff(LB1))
MaxDiff2 = Me.GetMaxDiff(LR2)
MaxDiff2 = Math.Max(MaxDiff2, Me.GetMaxDiff(LG2))
MaxDiff2 = Math.Max(MaxDiff2, Me.GetMaxDiff(LB2))
If MaxDiff1 > MaxDiff2 Then
D = MaxDiff1 - MaxDiff2
Factor = D / 255
Factor = Factor / (AmplifierPercent / 100)
Factor = Math.Min(Factor, 1)
Factor = 1 - Factor ''invert result
''TB.Math.Swap(MaxDiff1, MaxDiff2)
''Factor = 255 ''the original BM1 is better
Else
D = MaxDiff2 - MaxDiff1
Factor = D / 255
Factor = Factor * (AmplifierPercent / 100)
Factor = Math.Min(Factor, 1)
''Factor = 0 ''the BM2 is better
End If
Factor = Factor * 255
C1 = Color.FromArgb(Convert.ToByte(Factor), C1.R, C1.G, C1.B)
End Sub