Nano Hash - криптовалюты, майнинг, программирование

Масштабируйте изображение с помощью SRT до минимально возможного соотношения с помощью imagemagick

Это дополнительный вопрос к Обрезке и изменении размера изображения вокруг настраиваемая точка фокусировки, где я получил полезные ответы о том, какие части команды использовать для imagemagick, чтобы достичь того, что я хочу: уменьшить масштаб изображения, но вместо использования предопределенной гравитации (например, «Центр» или «Север») , Я хочу использовать настраиваемую точку фокусировки на изображении, которая должна быть новым центром масштабированного изображения, чтобы гарантировать, что «важная точка» изображения всегда видна при обрезке / изменении размера.

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

Чем я сейчас занимаюсь:

# Example image from https://unsplash.com/photos/p-I9wV811qk
source_image = 'input.jpg'

source_image_size = [3008, 2000]
target_image_size = [295, 195]

# Focus point position, in percentages.
focus_point = {
  x: 46.7087766,
  y: 24.2
}

# Calculate the focus point in px on the source image.
source_focus_point = [
  source_image_size[0] / 100.0 * focus_point[:x],
  source_image_size[1] / 100.0 * focus_point[:y]
]

# Calculate the distances to the focus point in percentage,
# from all four image sides, and use the smalles value.
smallest_percentage_distance = [
  focus_point[:x],
  (100.0 - focus_point[:x]),
  focus_point[:y],
  (100.0 - focus_point[:y])
].min

# Scale image to reach smallest percentage distance.
scale_factor = smallest_percentage_distance / 100.0

# Calculate the focus point on the target image for the transformation,
# which will be on the center of the new image.
target_focus_point = [
  target_image_size[0].to_f / 2.0,
  target_image_size[1].to_f / 2.0
]

# Define how many degrees the image should be rotated.
rotation_degrees = 0

command = [
  'convert',
  source_image,
  "-set option:distort:viewport #{target_image_size.join('x')}",
  "-distort SRT '#{source_focus_point.join(',')} #{scale_factor} #{rotation_degrees} #{target_focus_point.join(',')}'",
  'output2.jpg'
].join ' '

Итоговая команда:

convert input.jpg -set option:distort:viewport 295x195 -distort SRT '1405.000000128,484.0 0.242 0 147.5,97.5' output.jpg

Насколько я понимаю, второй аргумент distort SRT imagemagick (здесь scale_factor) определяет, насколько в% изображение должно быть уменьшено. Моя идея заключалась в том, чтобы вычислить расстояния от всех сторон до точки фокусировки, взять наименьшее расстояние, преобразовать его в подходящий аргумент и использовать его для определения величины масштабирования.

Цель состоит в том, чтобы максимально масштабировать изображение, чтобы изображение на выходе не обрезалось слишком сильно, чтобы показать как можно больше исходного изображения. Мой вывод сейчас слишком сильно отрезает.

Я попытался визуализировать это для лучшего понимания:  введите описание изображения здесь

Исходное изображение можно найти здесь: https://unsplash.com/photos/p-I9wV811qk

Что я делаю неправильно? Как правильно рассчитать значение для уменьшения масштаба изображения, чтобы было видно как можно больше изображения?


Редактировать 1
В конце будет создано несколько вариантов изображения с разными соотношениями сторон. Рядом с заданными 295x195 будет еще один размер 1440x560; Особенно в этом случае простое «кадрирование с гравитацией», скорее всего, обрежет среднюю или верхнюю часть изображения, таким образом, точку фокусировки, чтобы гарантировать, что жизненно важная часть всегда видна.


Редактировать 2 на ответ от fmw42
Код работает до сих пор, так что изменение размера и обрезка выполняется без использования SRT. К сожалению, результат далек от того, который у меня есть сейчас (но, возможно, я сделал что-то не так при адаптации сценария).

То, что я сделал, было

  • используя изображение из моего вопроса
  • замена px и py значениями точки фокусировки из моего вопроса
  • сохраняя расчет scale, но используя wd=295 и ht=195, поскольку это желаемая целевая культура

Результат выглядит следующим образом:  введите описание изображения здесь


  • Вам не нужно идти на все эти хлопоты. Просто масштабируйте все изображение на любой процент, который хотите. Все будет там. Затем обрежьте нужную область, вычислив точку с уменьшенным масштабом относительно центра. И обрезка с центром тяжести. 16.04.2020
  • Я не знаю, каков процент уменьшения, чтобы все было видно, это в основном главный вопрос; Как рассчитать это на основе имеющейся у меня информации (исходный размер изображения, размер целевого изображения, координаты точки фокусировки x, y). Если я просто уменьшу масштаб, а затем кадрирую с центром тяжести, насколько я понимаю, кадрирование начнется с центра изображения, но это не повлияет на точку фокусировки, которая может быть сверху или снизу. 16.04.2020
  • Если вы используете -resize WxH (в пикселях или процентах), изменяется размер всего изображения. Так что все видно и ничего не обрезано. Просто вычислите смещение точки от центра во входных данных и масштабируйте его, чтобы вычислить смещение в уменьшенной версии. Используйте -gravity center -crop для любого размера, который вы хотите. 16.04.2020
  • Звучит как хороший план. Не могли бы вы привести пример? Я поигрался с изменением размера, но немного не понимаю, как именно реализовать вашу идею. 16.04.2020
  • Отредактировал свой вопрос (отредактируйте 1 внизу вопроса), так как я считаю, что вариант использования может быть важным. 16.04.2020

Ответы:


1

Вот как я бы сделал это в Imagemagick (синтаксис Unix)

Вход:

введите описание изображения здесь

# get image dimensions and aspect ratio
WxH=`convert barn.jpg -format "%wx%h" info:`
ww=`echo "$WxH" | cut -dx -f1`
hh=`echo "$WxH" | cut -dx -f2`
aspect=`convert xc: -format "%[fx:$ww/$hh]" info:`

# define centering point
px=200
py=200

# compute distances to each side of the image
dleft=$px
dright=$((ww-px-1))
dtop=$py
dbottom=$((hh-py-1))

# find the minimum distance and to which side
dminx=`convert xc: -format "%[fx:round(min($dleft,$dright))]" info:`
dminy=`convert xc: -format "%[fx:round(min($dtop,$dbottom))]" info:`
dmin=`convert xc: -format "%[fx:round(min($dminx,$dminy))]" info:`

# compute crop width, height and scale percent
if [ $dmin -eq $dminx ]; then
wd=$((2*dminx))
ht=`convert xc: -format "%[fx:round($wd/$aspect)]" info:`
scale=`convert xc: -format "%[fx:100*$ww/$wd]" info:`
else
ht=$((2*dminy))
wd=`convert xc: -format "%[fx:round($ht*$aspect)]" info:`
scale=`convert xc: -format "%[fx:100*$hh/$ht]" info:`
fi

# compute x and y offsets to the top left corner of crop region
xoff=`convert xc: -format "%[fx:round($px-$wd/2)]" info:`
yoff=`convert xc: -format "%[fx:round($py-$ht/2)]" info:`

# crop and resize the image to original dimensions
convert barn.jpg -crop ${wd}x${ht}+${xoff}+${yoff} +repage -resize $scale% barn_result.jpg


Результат:

введите описание изображения здесь

16.04.2020
  • Большое спасибо за ваш ответ! Я просто нашел время, чтобы прочитать его и попробовать. Он в основном работает, но имеет ту же проблему, что и у меня в моем вопросе, с точки зрения неправильного масштабного коэффициента, в результате чего на изображении не отображается объем информации. Я обновил свой вопрос, указав, что я сделал и каков результат вашего ответа. 28.04.2020
  • Я думал, вы хотите увеличить масштаб кадрирования до полного размера ввода. Но похоже, что все, что вам нужно, это обрезать без изменения масштаба, но с тем же аспектом, что и входные данные. Это верно? 28.04.2020
  • Ах я вижу. Цель состоит в том, чтобы обрезать изображение до различных размеров с различными используемыми пропорциями (наиболее распространенными являются два размера: 295x195 и 1440x560, если изображение достаточно большое). Обрезанная версия должна максимально отображать само изображение. Это то, что я попытался объяснить в своей первой визуализации, где вы можете увидеть ожидаемый результат с рамкой вокруг изображения, которая показывает размер изображения без кадрирования, но с измененным размером. Его следует уменьшить как можно больше, чтобы показать как можно больше. 29.04.2020
  • Если центральная точка находится слишком близко к краю изображения, возможно, она не поддерживает ни один из этих размеров или соотношений сторон. Что вы хотите сделать в таких случаях? Должно ли изображение быть меньше желаемого размера или дополнено черным или прозрачным? Или нужно сохранить желаемый размер и желаемый центр не в центре? 30.04.2020
  • Я принял ваш ответ, так как это был главный момент в поиске решения. По сути, я просто добавил расстояние от точки фокусировки до центра к вычислению масштабирования, а затем сместил изображение на это значение, чтобы было достаточно места для смещения изображения, достаточного для отображения и всегда чтобы точка фокусировки была видимой. 30.04.2020
  • Итак, это решено для вас? Мне нужно попробовать еще раз? 30.04.2020
  • Пока он работает, возможно, он получит обновление позже, поэтому я считаю, что это решено. 01.05.2020

  • 2

    Если центральная точка находится слишком близко к краю изображения, возможно, она не поддерживает ни один из этих размеров или соотношений сторон. Что вы хотите сделать в таких случаях? Должно ли изображение быть меньше желаемого размера или дополнено черным или прозрачным? Или нужно сохранить желаемый размер и желаемый центр не в центре?

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

    И снова синтаксис Unix.

    Вход:

    введите описание изображения здесь

    Желаемая точка на 200 200:

    cd
    cd desktop
    infile="barn.jpg"
    inname=`convert "$infile" -format "%t" info:`
    # get image dimensions and aspect ratio
    WxH=`convert "$infile" -format "%wx%h" info:`
    ww=`echo "$WxH" | cut -dx -f1`
    hh=`echo "$WxH" | cut -dx -f2`
    
    # define centering point
    px=50
    py=50
    
    # define crop size
    wd=295
    ht=195
    
    # check if enough space on each side
    left=`convert xc: -format "%[fx:round($px-$wd/2)]" info:`
    left=`convert xc: -format "%[fx:$left<0?0:$left]" info:`
    right=`convert xc: -format "%[fx:$left+$wd-1]" info:`
    right=`convert xc: -format "%[fx:$right>$ww-1?$ww-1:$right]" info:`
    top=`convert xc: -format "%[fx:round($py-$ht/2)]" info:`
    top=`convert xc: -format "%[fx:$top<0?0:$top]" info:`
    bottom=`convert xc: -format "%[fx:$top+$ht-1]" info:`
    bottom=`convert xc: -format "%[fx:$bottom>$hh-1?$hh-1:$bottom]" info:`
    
    # compute crop values
    xoff=$left
    yoff=$top
    width=`convert xc: -format "%[fx:round($right-$left+1)]" info:`
    height=`convert xc: -format "%[fx:round($bottom-$top+1)]" info:`
    echo "$left; $right; $top; $bottom;"
    echo "$xoff; $yoff; $width; $height"
    
    # crop and resize the image to original dimensions
    convert "$infile" -fill red -draw "translate $px,$py circle 0,0 0,2" -alpha off \
    -crop ${width}x${height}+${xoff}+${yoff} +repage ${inname}_${px}_${py}.jpg
    


     введите описание изображения здесь

    Желаемая точка на 50,50:

    введите описание изображения здесь

    30.04.2020
  • Хороший вопрос, я бы сказал, что размер целевого кадра должен быть таким же, но, возможно, тогда точка фокусировки будет не по центру, а где-то еще, но, по крайней мере, видна на целевом кадре. Или я мог бы ограничить точку фокусировки определенной областью для пользовательского ввода. Я только что попробовал ваше второе решение, большое спасибо, что нашли время! Если я правильно понял, вы вообще не уменьшаете масштаб изображения? Это не решит мою проблему, поскольку главный вопрос заключается в том, как максимально уменьшить масштаб, чтобы большая часть изображения была видна при сохранении точки фокусировки (если возможно, как вы просили). 30.04.2020
  • Я предполагаю, что мой комментарий к вашему другому комментарию ответа был недостаточно ясным, извините за это. Итак, цель, которую я попытался объяснить, заключается в следующем: максимально уменьшить масштаб изображения, чтобы оно уместилось на желаемом холсте, и попытаться сохранить точку фокусировки. В моем первом редактировании я добавил к вопросу два размера кадрирования: 295x195 и 1440x560, поэтому соотношение сторон на входе не такое же, как на выходе. 30.04.2020
  • OK. Я попробую еще раз сегодня позже, если у меня будет время. Но понимаю ли я, что точка фокусировки должна находиться в центре уменьшенного изображения? 30.04.2020
  • Я задумался. В идеале он должен быть в центре, но, как вы отметили, это не будет работать в зависимости от того, где он находится (например, рядом с границами), поэтому текущее решение, которое у меня есть, помещает точку фокусировки в то же положение на целевом изображении, что и был на исходном изображении (например, x = 20%, y = 15%). 01.05.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..