admin管理员组文章数量:1332896
I am somehow new to python and would like to get rid of use of for loop as it makes the program very slow. So I would like vectorize it. however, I am not sure how would I use it with two conditions Here I shared the code and would like someone could hit me..
image to be imported
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
def nothing(color):
pass
cv.namedWindow('Trackbar ')
cv.resizeWindow('Trackbar',800,200)
cv.createTrackbar('v_min','Trackbar ',0,255,nothing)
cv.createTrackbar('v_max','Trackbar ',0,255,nothing)
while True:
img_ = cv.imread('sat.png',cv.IMREAD_COLOR)
img_np=np.array(img_)
img2_np=np.array(img_)
value_min=cv.getTrackbarPos('v_min','Trackbar ')
value_max=cv.getTrackbarPos('v_max','Trackbar ')
height, width = img_np.shape[:2]
for j in range (0,width) :
for i in range (0,height):
for k in range (0,2):
if (value_min < img_np[i,j,k] <= value_max):
img2_np[i,j] = ((img_np[i,j]-value_min)/(value_max-value_min))*255
else:
img2_np[i,j] = 0
#Here is the vectorization to remove all for and if loop (what I think )
# img_np[(value_min < img_np.any() <= value_max)]=((img_np-value_min)/(value_max-value_min))*255 | img_np[(value_min > img_np.any() >= value_max)]=0
cv.imshow('FINAL IMAGE',img_np)
cv.imshow('image',img_)
kk = cv.waitKey(1000) & 0xFF # large wait time to remove freezing
if kk == 113 or kk == 27:
break
I am expecting to convert or I mean to remove all (for, if/else loop) with vectorize so less time.. so I tried first to with one if condition and seems working however, when I tried to add with two conditions like (|) else seems not working
I am somehow new to python and would like to get rid of use of for loop as it makes the program very slow. So I would like vectorize it. however, I am not sure how would I use it with two conditions Here I shared the code and would like someone could hit me..
image to be imported
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
def nothing(color):
pass
cv.namedWindow('Trackbar ')
cv.resizeWindow('Trackbar',800,200)
cv.createTrackbar('v_min','Trackbar ',0,255,nothing)
cv.createTrackbar('v_max','Trackbar ',0,255,nothing)
while True:
img_ = cv.imread('sat.png',cv.IMREAD_COLOR)
img_np=np.array(img_)
img2_np=np.array(img_)
value_min=cv.getTrackbarPos('v_min','Trackbar ')
value_max=cv.getTrackbarPos('v_max','Trackbar ')
height, width = img_np.shape[:2]
for j in range (0,width) :
for i in range (0,height):
for k in range (0,2):
if (value_min < img_np[i,j,k] <= value_max):
img2_np[i,j] = ((img_np[i,j]-value_min)/(value_max-value_min))*255
else:
img2_np[i,j] = 0
#Here is the vectorization to remove all for and if loop (what I think )
# img_np[(value_min < img_np.any() <= value_max)]=((img_np-value_min)/(value_max-value_min))*255 | img_np[(value_min > img_np.any() >= value_max)]=0
cv.imshow('FINAL IMAGE',img_np)
cv.imshow('image',img_)
kk = cv.waitKey(1000) & 0xFF # large wait time to remove freezing
if kk == 113 or kk == 27:
break
I am expecting to convert or I mean to remove all (for, if/else loop) with vectorize so less time.. so I tried first to with one if condition and seems working however, when I tried to add with two conditions like (|) else seems not working
Share Improve this question edited Nov 21, 2024 at 10:58 Momo R asked Nov 21, 2024 at 0:47 Momo RMomo R 113 bronze badges 4 |2 Answers
Reset to default 0Your code using for loops in that order is the worst possible way you could do it unless the images being processed have width, height of 2 or less.
for j in range (0,width) :
for i in range (0,height):
for k in range (0,2):
if (value_min < img_np[i][j][k] <= value_max):
img2_np[i][j] = ((img_np[i][j]-value_min)/(value_max-value_min))*255
else:
img2_np[i][j] = 0
The innermost loop has maximal setup overheads that way around.
It should be replaced by
for k in range (0,2):
for j in range (0,width) :
for i in range (0,height):
if (value_min < img_np[i][j][k] <= value_max):
img2_np[i][j][k] = ((img_np[i][j][k]-value_min)/(value_max-value_min))*255
else:
img2_np[i][j][k] = 0
I don't know how good the optimiser is in Python at removing loop invariants and strength reduction so it might also be worth manually moving the scaling out of the loop and multiplying rather than dividing. Division is the most expensive binary arithmetic operation ~10x slower than +,-,*
.
scalefactor = 255/(value_max-value_min)
...
if (value_min < img_np[i][j][k] <= value_max):
img2_np[i][j][k] = ((img_np[i][j][k]-value_min)*scalefactor
else:
img2_np[i][j][k] = 0
You also need to check the memory allocation rules for 3D arrays in Python to ensure you are making sequential memory access if the arrays are large.
Without actually testing this, this change should work - assuming in 1 condition more or less works.
img_np2 = np.zeros_like(img_np2) # default 0s
cond = (value_min < img_np) & (img_np <= value_max)
img_np2[cond] = ((img_np[cond]-value_min)/(value_max-value_min))*255
alternatively
img_np2 = np.where(cond, ((img_np-value_min)/(value_max-value_min))*255, 0)
a<x<=b
only works with scalar x
. for array, it needs to be separated into two clauses, ()&()
.
The where
version evaluates at all points, but that should be ok here. Sometimes we want conditional evaluation to avoid things like run time errors, divide by zero, etc. Then we need to use the first version, or use the where
clause in a ufunc
(like np.divide
).
本文标签: numpyVectorization with ifelse conditions PythonStack Overflow
版权声明:本文标题:numpy - Vectorization with ifelse conditions Python - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742320379a2452665.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
img2_np[i][j][k]
in your if/else statement? I'm not quite sure what you want to happen when k=0 gives you theif
side and k=1 gives you the else side. (ps. In numpy, it's equivalent and more conventional to writeimg2_np[i, j, k]
wheni
,j
, andk
are integers. – Frank Yellin Commented Nov 21, 2024 at 1:19