2017-01-06 8 views
1

Я пытаюсь преобразовать изображение 640x360 через функцию переназначения OpenCV (в python 2.7). Шаги, выполненные являются следующимиИспользование функции переназначения OpenCV crop image

  1. Генерировать кривую и хранить ее координату х и у в двух отдельных массивах, curve_x и curve_y.I прилагают сгенерированные кривой в виде изображения (с использованием pyplot): Curve

  2. нагрузки изображения с помощью функции OpenCV imread

    original = cv2.imread('C:\\Users\\User\\Desktop\\alaskan-landscaps3.jpg') 
    
  3. Выполнить вложенный цикл таким образом, что каждый пиксель сдвигается вверх в пропорции к высоте кривой в том, что каждый пиксель point.For я Calculat e коэффициент деформирования путем деления расстояния между координатой y кривой и «потолком» (360) на высоту изображения. Затем коэффициент умножается на расстояние между y-координатой пикселя и «потолком», чтобы найти новое расстояние, которое пиксель должен иметь от «потолка» (он будет короче, так как у нас есть сдвиг вверх). Наконец, я вычитаю это новое расстояние от «потолка», чтобы получить новую координату y для пикселя. Я думал об этой формуле, чтобы гарантировать, что все записи в массиве map_y, используемые в функции переназначения, будут находиться в области исходного изображения.

    for i in range(0, y_size): 
        for j in range(0,x_size): 
         map_y[i][j]= y_size-((y_size - i) * ((y_size - curve_y[j])/y_size)) 
         map_x[i][j]=j` 
    
  4. Затем с помощью функции ReMap

    warped=cv2.remap(original,map_x,map_y,cv2.INTER_LINEAR) 
    

появляется Полученное изображение искаженным несколько вдоль пути кривой, но она обрезается - я прилагаю как оригинал и результирующее изображение

Images

Я знаю, что должен быть что-то не получается, но я не могу понять, где ошибка в моем коде - я не понимаю, почему, поскольку все y-координаты в map_y находятся между 0-360, верхняя треть изображения исчезла после переопределения

Любые указатели или помощь будут оценены. Благодаря

[EDIT:] Я редактировал свою функцию следующим образом:

#array to store previous y-coordinate, used as a counter during mapping process 
floor_y=np.zeros((x_size),np.float32) 
#for each row and column of picture 
for i in range(0, y_size): 
    for j in range(0,x_size): 
     #calculate distance between top of the curve at given x coordinate and top 
     height_above_curve = (y_size-1) - curve_y_points[j] 
     #calculated a mapping factor, using total height of picture and distance above curve 
     mapping_factor = (y_size-1)/height_above_curve 
     # if there was no curve at given x-coordinate then do not change the pixel coordinate 
     if(curve_y_points[j]==0): 
      map_y[i][j]=j 
     #if this is the first time the column is traversed, save the curve y-coordinate 
     elif (floor_y[j]==0): 
      #the pixel is translated upwards according to the height of the curve at that point 
      floor_y[j]=i+curve_y_points[j] 
      map_y[i][j]=i+curve_y_points[j] # new coordinate saved 
     # use a modulo operation to only translate each nth pixel where n is the mapping factor. 
     # the idea is that in order to fit all pixels from the original picture into a new smaller space 
     #(because the curve squashes the picture upwards) a number of pixels must be removed 
     elif ((math.floor(i % mapping_factor))==0): 
      #increment the "floor" counter so that the next group of pixels from the original image 
      #are mapped 1 pixel higher up than the previous group in the new picture 
      floor_y[j]=floor_y[j]+1 
      map_y[i][j]=floor_y[j] 
     else: 
      #for pixels that must be skipped map them all to the last pixel actually translated to the new image 
      map_y[i][j]=floor_y[j] 
     #all x-coordinates remain unchanges as we only translate pixels upwards 
     map_x[i][j] = j 
#printout function to test mappings at x=383 
for j in range(0, 360): 
    print('At x=383,y='+str(j)+'for curve_y_points[383]='+str(curve_y_points[383])+' and floor_y[383]='+str(floor_y[383])+' mapping is:'+str(map_y[j][383])) 

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

The top of the curved part is at around y=140 in the original picture yet now is very close to the top i.e y around 300

Я думаю, что, может быть, есть что-то происходит с порядком строк и столбцов в массиве map_y?

+0

Кнопка {} не отформатировала образцы кода, которые я опубликовал, и я не знаю почему. Я пытаюсь отформатировать код так, чтобы он был разборчивым - извинения, если вы прочитали сообщение, прежде чем я его обработаю. – Socrats

+0

Отступы с 4 пробелами не работали, но обратные образы, похоже, сработали. – Socrats

+0

С помощью редактора: «Если вы хотите иметь предварительно отформатированный блок в списке, отступ на восемь пробелов». Более подробная информация содержится в [расширенной помощи] (http://stackoverflow.com/editing-help#advanced-lists). –

ответ

0

Я не думаю, что изображение обрезается. Скорее, значения «переполнены» в верхнем среднем пикселе, поэтому они перезаписываются. Рассмотрим следующий пример с простой функцией на шахматной доске.

import numpy as np 
import cv2 
import pickle 

y_size=200 
x_size=200 

x=np.linspace(0,x_size,x_size+1) 
y=(-(x-x_size/2)*(x-x_size/2))/x_size+x_size 
plt.plot(x,y) 

Функция выглядит следующим образом: The curve

Тогда давайте получить изображение с обычным рисунком.

test=np.zeros((x_size,y_size),dtype=np.float32) 

for i in range(0, y_size): 
    for j in range(0,x_size): 
     if i%2 and j%2: 
      test[i][j]=255 
cv2.imwrite('checker.png',test) 

regular pattern

Теперь применить функцию сдвига для этой модели:

map_y=np.zeros((x_size,y_size),dtype=np.float32) 
map_x=np.zeros((x_size,y_size),dtype=np.float32) 

for i in range(0, y_size): 
    for j in range(0,x_size): 
     map_y[i][j]= y_size-((y_size - i) * ((y_size - y[j])/y_size)) 
     map_x[i][j]=j 

warped=cv2.remap(test,map_x,map_y,cv2.INTER_LINEAR) 

cv2.imwrite('warped.png',warped) 

enter image description here

Если вы заметили, из-за сдвига, более чем одно значение соответствует верхние-средние области, что делает его похожим на обрезание. Но если вы посмотрите в верхний левый и правый углы изображения, обратите внимание, что значения являются более разреженными, поэтому эффект «обрезки» не так много. Надеюсь, что простой пример помогает лучше понять, что происходит.

+0

Это действительно помогает, спасибо. Поэтому я предполагаю, что мне нужна более сложная функция для деформации этой части изображения. В основном, эффект, на который я нацелился, заключается в том, что верхняя часть изображения появляется «раздавлена» из-за сдвига вверх. Существуют ли какие-либо реализации Python/OpenCV, которые могут вызвать аналогичный эффект? – Socrats

+0

Привет, я пересмотрел свою функцию сопоставления с учетом того, что вы описали, но я все еще получаю нечетный эффект, который я не могу объяснить [Вопрос обновлен новым кодом] – Socrats

 Смежные вопросы

  • Нет связанных вопросов^_^