bitwise_and addweighted python opencv image-processing computer-vision alphablending

addweighted - bitwise_and opencv python



¿Cómo obtener el valor alfa correcto para combinar perfectamente dos imágenes? (2)

Hay 2 problemas obvios con sus imágenes:

  1. El área de la frontera tiene condiciones de iluminación distorsionadas

    Eso es muy probablemente causado por la óptica utilizada para adquirir imágenes. Por lo tanto, para remediar esto, debe usar solo dentro de una parte de las imágenes (recorte algunos píxeles del borde.

    Entonces, cuando corté 20 píxeles del borde y mezclé con la iluminación común, obtuve esto:

    Como puede ver, la fea costura de borde está ausente ahora, solo persisten los problemas de iluminación (ver punto # 2 ).

  2. Las imágenes se toman en diferentes condiciones de iluminación

    Aquí los efectos de dispersión subsuperficial impactan al hacer que las imágenes "no sean compatibles". Debes normalizarlos para obtener una iluminación uniforme o postprocesar el resultado combinado línea por línea y cuando el tope coherente detectado multiplique el resto de la línea para que la protuberancia disminuya.

    Entonces, el resto de la línea debe multiplicarse por la constante i0/i1 . Este tipo de golpes solo pueden ocurrir en los bordes entre los valores de superposición para que pueda escanearlos o usar esas posiciones directamente ... Para reconocer un bache válido, debe tener vecinos cercanos en las líneas anterior y siguiente a lo largo de toda la altura de la imagen.

    También puedes hacer esto en la dirección del eje y de la misma manera ...

He intentado mezclar dos imágenes. El enfoque actual que estoy tomando es, obtengo las coordenadas de la región superpuesta de las dos imágenes, y solo para las regiones superpuestas, combino con un alfa codificado de 0.5, antes de agregarlo. Así que, básicamente, solo tomo la mitad del valor de cada píxel de las regiones superpuestas de ambas imágenes y las agrego. Eso no me da una mezcla perfecta porque el valor alfa está codificado a 0.5. Este es el resultado de la combinación de 3 imágenes:

Como puede ver, la transición de una imagen a otra sigue siendo visible. ¿Cómo obtengo el valor alfa perfecto que eliminaría esta transición visible? ¿O no existe tal cosa, y estoy tomando un enfoque equivocado?

Así es como estoy haciendo la mezcla:

for i in range(3): base_img_warp[overlap_coords[0], overlap_coords[1], i] = base_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 next_img_warp[overlap_coords[0], overlap_coords[1], i] = next_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 final_img = cv2.add(base_img_warp, next_img_warp)

Si alguien quisiera darle una oportunidad, aquí hay dos imágenes deformadas y la máscara de su región superpuesta: http://imgur.com/a/9pOsQ


Esta es la manera en que lo haría en general:

int main(int argc, char* argv[]) { cv::Mat input1 = cv::imread("C://Input/pano1.jpg"); cv::Mat input2 = cv::imread("C://Input/pano2.jpg"); // compute the vignetting masks. This is much easier before warping, but I will try... // it can be precomputed, if the size and position of your ROI in the image doesnt change and can be precomputed and aligned, if you can determine the ROI for every image // the compression artifacts make it a little bit worse here, I try to extract all the non-black regions in the images. cv::Mat mask1; cv::inRange(input1, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask1); cv::Mat mask2; cv::inRange(input2, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask2); // now compute the distance from the ROI border: cv::Mat dt1; cv::distanceTransform(mask1, dt1, CV_DIST_L1, 3); cv::Mat dt2; cv::distanceTransform(mask2, dt2, CV_DIST_L1, 3); // now you can use the distance values for blending directly. If the distance value is smaller this means that the value is worse (your vignetting becomes worse at the image border) cv::Mat mosaic = cv::Mat(input1.size(), input1.type(), cv::Scalar(0, 0, 0)); for (int j = 0; j < mosaic.rows; ++j) for (int i = 0; i < mosaic.cols; ++i) { float a = dt1.at<float>(j, i); float b = dt2.at<float>(j, i); float alpha = a / (a + b); // distances are not between 0 and 1 but this value is. The "better" a is, compared to b, the higher is alpha. // actual blending: alpha*A + beta*B mosaic.at<cv::Vec3b>(j, i) = alpha*input1.at<cv::Vec3b>(j, i) + (1 - alpha)* input2.at<cv::Vec3b>(j, i); } cv::imshow("mosaic", mosaic); cv::waitKey(0); return 0; }

Básicamente se calcula la distancia desde el límite de ROI al centro de los objetos y se calcula el alfa de ambos valores de máscara de fusión. Entonces, si una imagen tiene una gran distancia desde el borde y otra a una distancia baja desde el borde, usted prefiere el píxel más cercano al centro de la imagen. Sería mejor normalizar esos valores para los casos en que las imágenes deformadas no son de tamaño similar. Pero aún mejor y más eficiente es precalcular las máscaras de mezcla y deformarlas. Lo mejor sería conocer el viñeteado de su sistema óptico y elegir una máscara de fusión idéntica (por lo general, valores más bajos del borde).

Del código anterior obtendrás estos resultados: máscaras de ROI:

Las máscaras de fusión (como una impresión, deben ser matrices flotantes en su lugar):

mosaico de la imagen: