@@ -409,6 +409,8 @@ def create_image_pyramids(self, images: "list[np.ndarray]",
409
409
g_pyramids = []
410
410
l_pyramids = []
411
411
412
+ actual_pyramid_levels = self .pyramid_levels
413
+
412
414
for image , weight in zip (images , weights ):
413
415
gaussian_pyramid = []
414
416
@@ -418,31 +420,35 @@ def create_image_pyramids(self, images: "list[np.ndarray]",
418
420
# Create gaussian pyramid
419
421
for i in range (self .pyramid_levels ):
420
422
if i == 0 :
421
- gaussian_pyramid .append (weight )
423
+ gaussian_pyramid .append (np . float64 ( weight / 255 ) )
422
424
else :
423
425
gaussian_pyramid .append (cv2 .pyrDown (gaussian_pyramid [- 1 ]))
426
+ if gaussian_pyramid [- 1 ].shape [0 ] < 8 or gaussian_pyramid [- 1 ].shape [1 ] < 8 :
427
+ actual_pyramid_levels = i + 1
428
+ break
424
429
425
- # Display gaussian pyramid
430
+ # Create image gaussians
431
+ for i in range (actual_pyramid_levels ):
426
432
427
- # Create gaussian pyramid for image
428
- for i in range (self .pyramid_levels ):
429
433
if i == 0 :
430
- image_gaussians .append (image )
434
+ image_gaussians .append (np . float64 ( image / 255 ) )
431
435
else :
432
436
image_gaussians .append (cv2 .pyrDown (image_gaussians [- 1 ]))
433
437
434
- # Create laplacian pyramid
435
- for i in range (self .pyramid_levels - 1 , - 1 , - 1 ):
438
+ # Create Laplacian Pyramid
439
+ for i in range (actual_pyramid_levels ):
440
+
441
+ this_gaussian = image_gaussians [i ]
442
+ next_gaussian = image_gaussians [i + 1 ] if i < actual_pyramid_levels - \
443
+ 1 else np .zeros_like (image_gaussians [i ])
436
444
437
- if i == self . pyramid_levels - 1 :
438
- laplacian_pyramid .append (image_gaussians [ i ] )
445
+ if i == actual_pyramid_levels - 1 :
446
+ laplacian_pyramid .append (this_gaussian )
439
447
else :
440
- size = (image_gaussians [i ].shape [1 ],
441
- image_gaussians [i ].shape [0 ])
442
- gaussian_expanded = cv2 .pyrUp (
443
- image_gaussians [i + 1 ], dstsize = size )
444
- laplacian_pyramid .append (cv2 .subtract (
445
- image_gaussians [i ], gaussian_expanded ))
448
+ laplacian_pyramid .append (
449
+ cv2 .subtract (this_gaussian , cv2 .pyrUp (
450
+ next_gaussian , dstsize = this_gaussian .shape [:2 ][::- 1 ]))
451
+ )
446
452
447
453
g_pyramids .append (gaussian_pyramid )
448
454
l_pyramids .append (laplacian_pyramid )
@@ -467,23 +473,20 @@ def blend_pyramids(self, gaussian_pyramids: "list[list[np.ndarray]]",
467
473
"""
468
474
res_laplacian = []
469
475
470
- for level in range (self . pyramid_levels ):
476
+ for level in range (len ( gaussian_pyramids [ 0 ]) ):
471
477
472
- reverse_level = self .pyramid_levels - (1 + level )
473
-
474
- res_plevel = np .zeros (laplacian_pyramids [0 ][reverse_level ].shape ,
475
- dtype = np .uint8 )
478
+ res_plevel = np .zeros (laplacian_pyramids [0 ][level ].shape ,
479
+ dtype = np .float64 )
476
480
477
481
for img_idx in range (len (gaussian_pyramids )):
478
482
479
483
gaussian = gaussian_pyramids [img_idx ][level ]
480
- laplacian = laplacian_pyramids [img_idx ][reverse_level ]
481
-
482
- gaussian = np .float32 (gaussian / 255 )
484
+ laplacian = laplacian_pyramids [img_idx ][level ]
483
485
484
486
gaussian = np .repeat (gaussian [:, :, np .newaxis ], 3 , axis = 2 )
485
487
combination = cv2 .multiply (
486
- gaussian , laplacian , dtype = cv2 .CV_8UC3 )
488
+ gaussian , laplacian , dtype = cv2 .CV_64FC3 )
489
+
487
490
res_plevel = cv2 .add (res_plevel , combination )
488
491
489
492
res_laplacian .append (res_plevel )
@@ -505,14 +508,50 @@ def reconstruct_image(self, laplacian_pyramid: "list[np.ndarray]") -> np.ndarray
505
508
The final HDR image
506
509
"""
507
510
508
- laplacian_pyramid = laplacian_pyramid [:: - 1 ]
511
+ res = laplacian_pyramid [- 1 ]
509
512
510
- res = laplacian_pyramid [ 0 ]
513
+ for i in range ( len ( laplacian_pyramid ) - 2 , 0 , - 1 ):
511
514
512
- for i in range ( 1 , len ( laplacian_pyramid )):
515
+ # Display laplacian pyramid
513
516
size = (laplacian_pyramid [i ].shape [1 ],
514
517
laplacian_pyramid [i ].shape [0 ])
515
518
res = cv2 .pyrUp (res , dstsize = size )
516
- res = cv2 .add (res , laplacian_pyramid [i ])
519
+ res = cv2 .add (res , laplacian_pyramid [i ], dtype = cv2 .CV_64FC3 )
520
+
521
+ res = cv2 .normalize (res , None , 0 , 255 , cv2 .NORM_MINMAX , cv2 .CV_8UC3 )
517
522
518
523
return res
524
+
525
+
526
+ """
527
+ Quick test of the ExposureFusion class
528
+ """
529
+ if __name__ == "__main__" :
530
+
531
+ images = [
532
+ "images\statues\one\HDR_test_scene_1__1.1.1.png" ,
533
+ "images\statues\one\HDR_test_scene_1__1.1.2.png" ,
534
+ "images\statues\one\HDR_test_scene_1__1.1.3.png" ,
535
+ "images\statues\one\HDR_test_scene_1__1.1.4.png" ,
536
+ "images\statues\one\HDR_test_scene_1__1.1.5.png"
537
+ ]
538
+
539
+ images = [cv2 .imread (image ) for image in images ]
540
+
541
+ fuser = ExposureFusion (pyramid_levels = 7 )
542
+
543
+ width , height = images [0 ].shape [:2 ]
544
+ aspect = width / height
545
+ width_new = 600
546
+ height_new = int (width_new / aspect )
547
+
548
+ try :
549
+ HDR = fuser (images )
550
+ cv2 .namedWindow ("HDR" , cv2 .WINDOW_NORMAL )
551
+ cv2 .resizeWindow ("HDR" , width_new , height_new )
552
+ cv2 .imshow ("HDR" , HDR )
553
+ cv2 .waitKey (0 )
554
+ except :
555
+ print ("Error displaying final img." )
556
+ finally :
557
+ cv2 .destroyAllWindows ()
0 commit comments