Тиснение изображения - PullRequest
       6

Тиснение изображения

2 голосов
/ 23 апреля 2011

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

  (define bound
      (lambda (n)
        (cond
          [(<= n 0) 0]
          [(>= n 255) 255]
          [else n])))

Bound принимает целое число и обрезает значения вне диапазона от 0 до 255 включительно до конечных точек.

(define boost
  (lambda (x)
    (bound (+ 127 x))))

Повышение принимает целое число, добавляет к нему 127, а затем ограничивает результат. Число 127 - фокус повышения, потому что мы будем использовать повышение, чтобы увеличить цвета, а 127 - половина диапазона цветового компонента.

(define image-emboss
  (lambda (img)
    (define emboss
      (lambda (r c)
        (let ([a (image-ref img r (add1 c))]
              [b (image-ref img (add1 r) (add1 c))]
              [c (image-ref img (sub1r) (add1 c))]
              [d (image-ref img r (sub1 c))]
              [e (image-ref img (sub1 r) (sub1 c))]
              [f (image-ref img (add1 r) (sub1 c))])
          (if (or (< r 0) (< c 0))
              img
              (make-image r c (boost (- (+ a b c) d e f)))))))
  (emboss r c)))

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

Image of pixels needed

Я пытался создать тиснение изображения: оно берет изображение и возвращает тисненую версию изображения. Пиксели по периметру неизменны. Этот процесс должен использовать make-image и image-ref.

Изображение-строки берет изображение и возвращает количество строк в изображении.

(define image-rows
  (lambda (img)
    (cond
     [(image? img 1 1) (vector-length (img))]
     [else
      (error 'image-rows (format "~a is not an image" img))])))

Image-cols берет изображение и возвращает количество столбцов в изображении.

(define image-cols
  (lambda (img)
    (cond
     [(image? img 1 1) (if (zero? (vector-length (img)))
                           0
                           (vector-length (vector-ref (img) 0)))]
     [else
      (error 'image-cols (format "~a is not an image" img))])))

Image-ref берет изображение, индекс строки и столбец индекса и возвращает пиксель.

(define image-ref
  (lambda (img r c)
    (if (not (image? img 0 0))
        (error 'image-ref "first argument is not an image"))
    (if (and (integer? r) (<= 0 r (- (image-rows img) 1)))
        (if (and (integer? c) (<= 0 c (- (image-cols img) 1)))
            (vector-ref (vector-ref (img) r) c)
            (error 'image-ref (format "~a is an illegal index" c)))
        (error 'image-ref (format "~a is an illegal index" r)))))

Make-image принимает строки, столбцы и процедуру.

(define make-image
  (lambda (rows cols . args)
    (let ([gen-proc
           (cond
            [(null? args) (lambda (i j rows cols) black)]
            [(not (null? (cdr args)))
             (error 'make-image "too many arguments")]
            [(color? (car args)) (lambda (i j rows cols) (car args))]
            [(procedure? (car args)) (car args)]
            [else (error 'make-image (format "unknown fill: ~s" 
                                             (car args)))])])
      (let ([img (make-vector rows)])
        (let loop ([i 0])
          (when (< i rows)
            (vector-set! img i 
                         (let ([row (make-vector cols)])
                           (let loop ([j 0])
                             (when (< j cols)
                               (vector-set! row j (gen-proc i j rows cols))
                               (loop (+ j 1))))
                           row))
            (loop (+ i 1))))
        (lambda () img)))))

Я проверяю это, загружая изображение и определяя его в реплее, затем рисуя изображение, используя процедуру, созданную моим проф.

В любом случае. Я думаю, что мой код близок к правильности, но я действительно не уверен, как его исправить. Если у кого-нибудь есть подсказка / лучшее объяснение, которое поможет мне разобраться в этом, я буду очень признателен. Спасибо

1 Ответ

1 голос
/ 23 апреля 2011

Хотя я не уверен, какие другие проблемы вы видите, одна вещь, которая поражает меня, - функция image-emboss, похоже, не имеет правильного потока оценки в данный момент. Из того, что я вижу, когда вы звоните image-emboss, вы передаете ему изображение, после чего он оценивает лямбду, которая оценивает лямбду для emboss, а затем вызывает emboss со значениями r и * 1006. * ... но вы не определили r и c в среде (то есть фрейме среды, созданном image-emboss лямбда-выражением), который emboss вызывает внутри. Как тогда интерпретатор схемы может оценить два символа r и c для правильного вызова лямбды, определенной emboss?

Я бы подумал, что по крайней мере ваш вызов emboss внутри image-emboss должен выглядеть скорее как (emboss (image-rows img) (image-cols img)), а не (emboss r c). Вызов (emboss (image-rows img) (image-cols img)) имеет символы, которые все могут быть оценены в кадре среды, определяемом image-emboss ... (emboss r c), с другой стороны, нет.

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

Надеюсь, это поможет,

Jason

...