video-input-psnr-ssim.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Python 2/3 compatibility
  4. from __future__ import print_function
  5. import numpy as np
  6. import cv2 as cv
  7. import argparse
  8. import sys
  9. # [get-psnr]
  10. def getPSNR(I1, I2):
  11. s1 = cv.absdiff(I1, I2) #|I1 - I2|
  12. s1 = np.float32(s1) # cannot make a square on 8 bits
  13. s1 = s1 * s1 # |I1 - I2|^2
  14. sse = s1.sum() # sum elements per channel
  15. if sse <= 1e-10: # sum channels
  16. return 0 # for small values return zero
  17. else:
  18. shape = I1.shape
  19. mse = 1.0 * sse / (shape[0] * shape[1] * shape[2])
  20. psnr = 10.0 * np.log10((255 * 255) / mse)
  21. return psnr
  22. # [get-psnr]
  23. # [get-mssim]
  24. def getMSSISM(i1, i2):
  25. C1 = 6.5025
  26. C2 = 58.5225
  27. # INITS
  28. I1 = np.float32(i1) # cannot calculate on one byte large values
  29. I2 = np.float32(i2)
  30. I2_2 = I2 * I2 # I2^2
  31. I1_2 = I1 * I1 # I1^2
  32. I1_I2 = I1 * I2 # I1 * I2
  33. # END INITS
  34. # PRELIMINARY COMPUTING
  35. mu1 = cv.GaussianBlur(I1, (11, 11), 1.5)
  36. mu2 = cv.GaussianBlur(I2, (11, 11), 1.5)
  37. mu1_2 = mu1 * mu1
  38. mu2_2 = mu2 * mu2
  39. mu1_mu2 = mu1 * mu2
  40. sigma1_2 = cv.GaussianBlur(I1_2, (11, 11), 1.5)
  41. sigma1_2 -= mu1_2
  42. sigma2_2 = cv.GaussianBlur(I2_2, (11, 11), 1.5)
  43. sigma2_2 -= mu2_2
  44. sigma12 = cv.GaussianBlur(I1_I2, (11, 11), 1.5)
  45. sigma12 -= mu1_mu2
  46. t1 = 2 * mu1_mu2 + C1
  47. t2 = 2 * sigma12 + C2
  48. t3 = t1 * t2 # t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
  49. t1 = mu1_2 + mu2_2 + C1
  50. t2 = sigma1_2 + sigma2_2 + C2
  51. t1 = t1 * t2 # t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
  52. ssim_map = cv.divide(t3, t1) # ssim_map = t3./t1;
  53. mssim = cv.mean(ssim_map) # mssim = average of ssim map
  54. return mssim
  55. # [get-mssim]
  56. def main():
  57. parser = argparse.ArgumentParser()
  58. parser.add_argument("-d", "--delay", type=int, default=30, help=" Time delay")
  59. parser.add_argument("-v", "--psnrtriggervalue", type=int, default=30, help="PSNR Trigger Value")
  60. parser.add_argument("-r", "--ref", type=str, default="Megamind.avi", help="Path to reference video")
  61. parser.add_argument("-t", "--undertest", type=str, default="Megamind_bugy.avi",
  62. help="Path to the video to be tested")
  63. args = parser.parse_args()
  64. sourceReference = args.ref
  65. sourceCompareWith = args.undertest
  66. delay = args.delay
  67. psnrTriggerValue = args.psnrtriggervalue
  68. framenum = -1 # Frame counter
  69. captRefrnc = cv.VideoCapture(cv.samples.findFileOrKeep(sourceReference))
  70. captUndTst = cv.VideoCapture(cv.samples.findFileOrKeep(sourceCompareWith))
  71. if not captRefrnc.isOpened():
  72. print("Could not open the reference " + sourceReference)
  73. sys.exit(-1)
  74. if not captUndTst.isOpened():
  75. print("Could not open case test " + sourceCompareWith)
  76. sys.exit(-1)
  77. refS = (int(captRefrnc.get(cv.CAP_PROP_FRAME_WIDTH)), int(captRefrnc.get(cv.CAP_PROP_FRAME_HEIGHT)))
  78. uTSi = (int(captUndTst.get(cv.CAP_PROP_FRAME_WIDTH)), int(captUndTst.get(cv.CAP_PROP_FRAME_HEIGHT)))
  79. if refS != uTSi:
  80. print("Inputs have different size!!! Closing.")
  81. sys.exit(-1)
  82. WIN_UT = "Under Test"
  83. WIN_RF = "Reference"
  84. cv.namedWindow(WIN_RF, cv.WINDOW_AUTOSIZE)
  85. cv.namedWindow(WIN_UT, cv.WINDOW_AUTOSIZE)
  86. cv.moveWindow(WIN_RF, 400, 0) #750, 2 (bernat =0)
  87. cv.moveWindow(WIN_UT, refS[0], 0) #1500, 2
  88. print("Reference frame resolution: Width={} Height={} of nr#: {}".format(refS[0], refS[1],
  89. captRefrnc.get(cv.CAP_PROP_FRAME_COUNT)))
  90. print("PSNR trigger value {}".format(psnrTriggerValue))
  91. while True: # Show the image captured in the window and repeat
  92. _, frameReference = captRefrnc.read()
  93. _, frameUnderTest = captUndTst.read()
  94. if frameReference is None or frameUnderTest is None:
  95. print(" < < < Game over! > > > ")
  96. break
  97. framenum += 1
  98. psnrv = getPSNR(frameReference, frameUnderTest)
  99. print("Frame: {}# {}dB".format(framenum, round(psnrv, 3)), end=" ")
  100. if (psnrv < psnrTriggerValue and psnrv):
  101. mssimv = getMSSISM(frameReference, frameUnderTest)
  102. print("MSSISM: R {}% G {}% B {}%".format(round(mssimv[2] * 100, 2), round(mssimv[1] * 100, 2),
  103. round(mssimv[0] * 100, 2)), end=" ")
  104. print()
  105. cv.imshow(WIN_RF, frameReference)
  106. cv.imshow(WIN_UT, frameUnderTest)
  107. k = cv.waitKey(delay)
  108. if k == 27:
  109. break
  110. sys.exit(0)
  111. if __name__ == "__main__":
  112. main()