Изменение размера изображения билинейной интерполяции и ближайшего соседа - PullRequest
0 голосов
/ 04 февраля 2020

В настоящее время у меня возникают проблемы с алгоритмом изменения масштаба и изображения. В настоящее время я хочу реализовать как билинейную интерполяцию, так и ближайший сосед. Я понимаю, как они оба концептуально работают, но я не могу записать это в код. То, что я все еще застрял на ближайшем соседе, я написал для него ниже псевдокод (основываясь на том, что я знаю):

    Resizing Images: Nearest Neighbour
    Use a loop:for j=0 to Yb-1
    for i=0 to Xb-1
    for c=0 to 2
   (floor) y=j*Ya/Yb 
   (floor) x=i*Xa/Xb
    Ib[j][i][c] = Ia[y][x][c]

Мой исходный набор данных (где я получаю объем данных) сохраняется в трехмерном массиве с [x] [y] [z] с (x, y, z). Я читаю каждый пиксель отдельно и могу рассчитать цвета для каждого пикселя, используя Color.color в java. Однако мне нужно знать, как получить цвет (c = [0,1,2]) для каждой позиции пикселя x и y (x, y), исключая z (для одного вида), чтобы преобразовать 1 старый пиксель для каждый новый пиксель в мой новый набор данных, содержащий новую ширину и высоту. Я написал большую часть кода, который я перевел выше в Java. Но я до сих пор не могу понять, как завершить работающую реализацию.

Заранее спасибо?

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

если я правильно понял, вы интерполируете объемы (вокселы) вместо пикселей в таком случае: пусть исходный объем vol1[xs1][ys1][zs1] и цель vol0[xs0][ys0][zs0], где xs,ys,zs - это разрешения, тогда ближайший сосед будет:

// vol0 <- vol1
for (              x0=0; x0<xs0; x0++)
 for (x1=(x*x1)/x0, y0=0; y0<ys0; y0++)
  for (y1=(y*y1)/y0, z0=0; z0<zs0; z0++)
   {    z1=(z*z1)/z0;
   vol0[x0][y0][z0]=vol1[x1][y1][z1];
   }

Цвет остается тем же для ближайшего соседа. В случае, если vol0 имеет меньшее разрешение, чем vol1, вы можете сделать циклы for с разрешением vol1 и вместо этого вычислить x0,y0,z0 из x1,y1,z1 для ускорения. Btw. все переменные являются целыми числами, для этого не нужно использовать числа с плавающей запятой ...

Теперь для цветовой кодировки на случай, если ваши вокселы представляют собой одномерный массив ({r,g,b}) вместо скалярного целочисленного типа:

vol0[xs0][ys0][zs0][3] 
vol1[xs1][ys1][zs1][3]

материал изменится на:

// vol0 <- vol1
for (              x0=0; x0<xs0; x0++)
 for (x1=(x*x1)/x0, y0=0; y0<ys0; y0++)
  for (y1=(y*y1)/y0, z0=0; z0<zs0; z0++)
   for (z1=(z*z1)/z0; i=0;  i<3;    i++ )
    vol0[x0][y0][z0][i]=vol1[x1][y1][z1][i];
1 голос
/ 05 февраля 2020

Я не очень знаком с java. Но вот рабочий код для python.

import cv2
import numpy as np

img = cv2.imread("image.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

scaleX = 0.5
scaleY = 0.5

newImg = np.zeros((int(img.shape[0]*scaleX),int(img.shape[1]*scaleY))).astype(np.uint8)

for y in range(newImg.shape[0]):
    for x in range(newImg.shape[1]):
        samplex = x/scaleX
        sampley = y/scaleY
        dx = samplex - np.floor(samplex)
        dy = sampley - np.floor(sampley)

        val = img[int(sampley-dy),int(samplex-dx)]*(1-dx)*(1-dy)
        val += img[int(sampley + 1 - dy),int(samplex-dx)]*(1-dx)*(dy) 
        val += img[int(sampley-dy),int(samplex + 1 - dx)]*(dx)*(1-dy)
        val += img[int(sampley + 1 -dy),int(samplex + 1 - dx)]*(dx)*(dy)

        newImg[y,x] = val.astype(np.uint8)


cv2.imshow("img",newImg)
cv2.waitKey(0)

Вы можете просто добавить еще один для l oop внутри них для и x для циклов для учета каналов.

...