estoy usando el siguiente código para agregar un poco de ruido a una imagen (directamente de la referencia OpenCV, página 449 - explicación de cv::Mat::begin
):Determinación del tipo de plantilla cuando se accede a los elementos OpenCV Mat
void
simulate_noise(Mat const &in, double stddev, Mat &out)
{
cv::Size s = in.size();
vector<double> noise = generate_noise(s.width*s.height, stddev);
typedef cv::Vec<unsigned char, 3> V4;
cv::MatConstIterator_<V4> in_itr = in.begin<V4>();
cv::MatConstIterator_<V4> in_end = in.end<V4>();
cv::MatIterator_<V4> out_itr = out.begin<V4>();
cv::MatIterator_<V4> out_end = out.end<V4>();
for (; in_itr != in_end && out_itr != out_end; ++in_itr, ++out_itr)
{
int noise_index = my_rand(noise.size());
for (int j = 0; j < 3; ++j)
(*out_itr)[j] = (*in_itr)[j] + noise[noise_index];
}
}
Nada excesivamente complicado:
in
yout
se asignancv::Mat
objetos de las mismas dimensiones y el tipo- iterate la imagen de entradasobre
- en cada posición, seleccione un valor aleatorio de
noise
(my_rand(int n)
devuelve un número aleatorio en[0..n-1]
- suma el píxel de
in
con el valor de ruido aleatorio - puso dan como resultado la suma en
out
No me gusta este código porque la siguiente declaración parece inevitable:
typedef cv::Vec<unsigned char, 3> V4;
Tiene codificadas de forma rígida dos cosas:
- Las imágenes tienen 3 canales
- La profundidad de canal se 8bpp
Si consigo este typedef
mal (por ejemplo, profundidad de canal incorrecta o número incorrecto de canales), entonces mi programa segmenta. Originalmente utilicé typedef cv::Vec<unsigned char, 4> V4
para manejar imágenes con un número arbitrario de canales (el máximo que admite OpenCV es 4), pero esto provocó una segfault.
¿Hay alguna manera de evitar las dos cosas anteriores? Idealmente, quiero algo que sea tan genérico como:
typedef cv::Vec<in.type(), in.size()> V4;
Gracias por la respuesta. Puede que termine usando punteros de fila como usted mencionó, pero se dice un poco que los iteradores van porque este es el lugar perfecto para usarlos. Además, incluso si configuro la función, aún tengo que especificar su nombre de tipo en el momento de la compilación, que realmente solo mueve el problema a otro punto del código. Tal vez estoy siendo un poco cínico, pero a mí me parece que especificar esta información en tiempo de compilación derrota el punto de tener plantillas y polimorfismo en primer lugar. – misha
No "solo" mueve el problema: si se fue sin la función de plantilla, tendría que replicar todo el código para el tipo. Además, el problema de fondo es que usted está tratando de operar en una imagen sin saber lo que contiene, y que está condenado al fracaso (por ejemplo, necesita diferentes ruido para imágenes de valores enteros que para las imágenes con valores reales. En el método Si vuelve generate_noise ruido gaussiano con media 0, el ruido tendrá una tendencia a oscurecer la imagen (debido enteros redondas _down_). – etarion
Y no, tener que especificar esta información en tiempo de compilación no derrotar el punto de tener plantillas , que se hizo para esta cosa exacta - y el polimorfismo es una cuestión completamente – etarion