2021年4月10日星期六

Speeding up custom adaptive smoothen filter with opencv in Python

I am new in Image Processing and trying to implement a custom filter I found in bibliography. I need to implement this in Python with opencv, but my implementation, though correct, is running really slowly. The algorithm can be described as follows:

  1. Calculate normalized chromatic distances in a 3x3 neighborhood around a centre point d_i = (|R_centre-R_i|+|G_centre-G_i|+|B_centre-B_i|)/(3x255) where centre point is the current pixel that iterates through whole picture, and i are the 8 points around it
  2. Having calculated values d_0 through d_7 we calculate an array of 8 elements called c_i = (1-d_i)^10 which will be the values used in our convolution box
  3. Our final convolution mask will be (1/sum(c))([c_0, c_1, c_2; c_3, 0 , c_4; c_5, c_6, c_7])* so basically c calues will be around and the centre point will be 0, and this matrix will be multiplied with the 9 pixels in the original image.
  4. Finally repeat the whole process for as many as iterations variables declares, usually around 10

For an image of size 677x450 it takes around 1 minute, which I think is too much. What could change to take better advantage of numpy's functionality, or anything else that would help speed it up?

As we can see from the photos the result is a lot more smooth, even after only 2 iterations
original photo adaptive smoothening

The code is as follows:

def adaptive_smoothening(img, iterations):      M, N, K = img.shape  # M: HEIGHT, N:WIDTH, K:CHANNELS      F = np.zeros([M, N, K], dtype=np.uint8)      for p in range(iterations):          print("Iteration ", p + 1)          r = img[:, :, 2]          g = img[:, :, 1]          b = img[:, :, 0]          m, n = r.shape  # m: height/channel , n: width/channel          c = np.zeros([8, 1])          d = np.zeros([8, 1])          for i in range(1, m):              for j in range(1, n):                  # Creating Neighborhood Indices                  ip = i + 1                  im = i - 1                  jm = j - 1                  jp = j + 1                  if im < 1:                      im = i                  elif ip > m - 1:                      ip = i - 1                  if jm < 1:                      jm = j                  elif jp > n - 1:                      jp = j - 1                  d[0] = (abs(int(r[i, j]) - int(r[i, jm])) + abs(int(g[i, j]) - int(g[i, jm])) + abs(                      int(b[i, j] - int(b[i, jm])))) / (3 * 255)                  d[1] = (abs(int(r[i, j]) - int(r[i, jp])) + abs(int(g[i, j]) - int(g[i, jp])) + abs(                      int(b[i, j] - int(b[i, jp])))) / (3 * 255)                  d[2] = (abs(int(r[i, j]) - int(r[ip, j])) + abs(int(g[i, j]) - int(g[ip, j])) + abs(                      int(b[i, j] - int(b[ip, j])))) / (3 * 255)                  d[3] = (abs(int(r[i, j]) - int(r[im, j])) + abs(int(g[i, j]) - int(g[im, j])) + abs(                      int(b[i, j] - int(b[im, j])))) / (3 * 255)                  d[4] = (abs(int(r[i, j]) - int(r[im, jm])) + abs(int(g[i, j]) - int(g[im, jm])) + abs(                      int(b[i, j] - int(b[im, jm])))) / (3 * 255)                  d[5] = (abs(int(r[i, j]) - int(r[ip, jm])) + abs(int(g[i, j]) - int(g[ip, jm])) + abs(                      int(b[i, j] - int(b[ip, jm])))) / (3 * 255)                  d[6] = (abs(int(r[i, j]) - int(r[ip, jp])) + abs(int(g[i, j]) - int(g[ip, jp])) + abs(                      int(b[i, j] - int(b[ip, jp])))) / (3 * 255)                  d[7] = (abs(int(r[i, j]) - int(r[im, jp])) + abs(int(g[i, j]) - int(g[im, jp])) + abs(                      int(b[i, j] - int(b[im, jp])))) / (3 * 255)                  c = [pow(1 - float(x), 10) for x in d]                  sum2 = sum(c)                  F[i, j, 2] = (1 / sum2) * (                          c[0] * r[i, jm] + c[1] * r[i, jp] + c[2] * r[ip, j] + c[3] * r[im, j] + c[4] * r[im, jm] +                          c[5] * r[ip, jm] + c[6] * r[ip, jp] + c[7] * r[im, jp])                  F[i, j, 1] = (1 / sum2) * (                          c[0] * g[i, jm] + c[1] * g[i, jp] + c[2] * g[ip, j] + c[3] * g[im, j] + c[4] * g[im, jm] +                          c[5] * g[ip, jm] + c[6] * g[ip, jp] + c[7] * g[im, jp])                  F[i, j, 0] = (1 / sum2) * (                          c[0] * b[i, jm] + c[1] * b[i, jp] + c[2] * b[ip, j] + c[3] * b[im, j] + c[4] * b[im, jm] +                          c[5] * b[ip, jm] + c[6] * b[ip, jp] + c[7] * b[im, jp])          img=F      return F    image = cv2.imread("HorVerTextDoc 001.jpg", 1 )  cv2.imshow("Original", resize(image, 0.5) )  result = adaptive_smoothening(resize(image,0.5),2)  cv2.imshow("Result",result)    
https://stackoverflow.com/questions/67001445/speeding-up-custom-adaptive-smoothen-filter-with-opencv-in-python April 08, 2021 at 05:47PM

没有评论:

发表评论