Python Opencv img.item() performance too slow
Question:
i wrote this little code to compare the pixels greyscale values of two 100×100 jpeg images.
However, the performance is very disappointing (1.5 Seconds for 10.000 comparisons). Is there a way to achieve a better performance?
Here is the code:
import cv2
import numpy as np
import math
import datetime
img1 = cv2.imread('Testbild 2014-08-23 17:27:25.141362.jpeg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('Testbild 2014-08-23 17:27:25.061802.jpeg', cv2.IMREAD_GRAYSCALE)
height, width =img1.shape
cnt = 0
threshold = 10
print("start:" + str(datetime.datetime.now()))
for y in range(0 , height):
for x in range(0 , width):
val1 = img1.item(y,x)
val2 = img2.item(y,x)
diff_abs = math.fabs(int(val1)-int(val2))
if diff_abs > threshold:
cnt += 1
if x == height and y == width:
break
if x == height:
x=0
if y == width:
y=0
print("end:" + str(datetime.datetime.now()))
print("Result: " + str(cnt))
Many thanks for your answers!
Answers:
The double loop:
for y in range(0 , height):
for x in range(0 , width):
val1 = img1.item(y,x)
val2 = img2.item(y,x)
diff_abs = math.fabs(int(val1)-int(val2))
if diff_abs > threshold:
cnt += 1
if x == height and y == width:
break
if x == height:
x=0
if y == width:
y=0
can be replaced by:
diff_abs = np.abs(img1-img2)
cnt = (diff_abs > threshold).sum()
This takes advantage of NumPy array’s ability to do fast element-wise arithmetic.
The condition
x == height and y == width
is never true. If height < width
, then y
will never equal width
(since y
is in range(0, height)
). If height > width
, then x
will never equal height
. and if height == width
, then neither x
nor y
will ever equal height
.
The condition
if x == height:
x=0
does nothing useful, since even if x == height
, the assignment to x
is lost on the next iteration of the loop.
The same goes for
if y == width:
y=0
i wrote this little code to compare the pixels greyscale values of two 100×100 jpeg images.
However, the performance is very disappointing (1.5 Seconds for 10.000 comparisons). Is there a way to achieve a better performance?
Here is the code:
import cv2
import numpy as np
import math
import datetime
img1 = cv2.imread('Testbild 2014-08-23 17:27:25.141362.jpeg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('Testbild 2014-08-23 17:27:25.061802.jpeg', cv2.IMREAD_GRAYSCALE)
height, width =img1.shape
cnt = 0
threshold = 10
print("start:" + str(datetime.datetime.now()))
for y in range(0 , height):
for x in range(0 , width):
val1 = img1.item(y,x)
val2 = img2.item(y,x)
diff_abs = math.fabs(int(val1)-int(val2))
if diff_abs > threshold:
cnt += 1
if x == height and y == width:
break
if x == height:
x=0
if y == width:
y=0
print("end:" + str(datetime.datetime.now()))
print("Result: " + str(cnt))
Many thanks for your answers!
The double loop:
for y in range(0 , height):
for x in range(0 , width):
val1 = img1.item(y,x)
val2 = img2.item(y,x)
diff_abs = math.fabs(int(val1)-int(val2))
if diff_abs > threshold:
cnt += 1
if x == height and y == width:
break
if x == height:
x=0
if y == width:
y=0
can be replaced by:
diff_abs = np.abs(img1-img2)
cnt = (diff_abs > threshold).sum()
This takes advantage of NumPy array’s ability to do fast element-wise arithmetic.
The condition
x == height and y == width
is never true. If height < width
, then y
will never equal width
(since y
is in range(0, height)
). If height > width
, then x
will never equal height
. and if height == width
, then neither x
nor y
will ever equal height
.
The condition
if x == height:
x=0
does nothing useful, since even if x == height
, the assignment to x
is lost on the next iteration of the loop.
The same goes for
if y == width:
y=0