Comment detail

モノクロ画像の類似検索 (Nested Flatten)
無駄に遠回りしてみました。
異なったピクセル数の集計をグラフィクスハードウェアにやらせています。
8bit/colorプレーンでオーバフローが起きないように、1024x768ぶんの
ビットマップを3分割し、R、G、Bコンポーネントがそれぞれ1または0の
512x512のテクスチャにして、それを256分割して32x32の正方形に加算で
貼込んで、CPU側に読み戻して集計してます。

残念ながら速度はそう速くなく、Pen4 2.0GHz/GeForce 6800/Linux で比較部分が 2.1秒程度。
細かく計測するとglBitmapでの転送がほとんどの時間(1.8秒以上)を占めています。
512x512 一枚の転送に6msくらいかかってるので何か間違えているの
だろうかとも思ったんですが、転送サイズを変えてみると綺麗にサイズに
比例してるし、glDrawPixelsなどはそんなに遅くないので、glBitmapで
巨大なイメージを送る方が悪いってことかなあ。(ドライバはNVIDIAのものです)。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
(use gl)
(use gl.glut)
(use gauche.uvector)
(use gauche.sequence)
(use gauche.time)
(use srfi-42)

(define *varray*
  (let1 v (make-f32vector (* 5 4 256))
    (do-ec (: x 16)
           (: y 16)
           (let ((ind (* (+ (* x 16) y) 5 4))
                 (x0  (/. x 16)) (x1 (/. (+ x 1) 16))
                 (y0  (/. y 16)) (y1 (/. (+ y 1) 16)))
             ;; (s, t, x, y, z) * 4
             (set! (subseq v ind (+ ind 20))
                   `(,x0 ,y0  0  0 0
                     ,x0 ,y1  0 32 0
                     ,x1 ,y1 32 32 0
                     ,x1 ,y0 32 0 0))))
    v))

(define *v1* (make-u8vector (* 32 32 3) 1))

(define *texname* 0)

(define (count-pixels bitmap)
  (define (draw-source cnt color)
    (gl-color color)
    (gl-raster-pos 0 0)
    (gl-bitmap 512 512 0 0 0 0
               (uvector-alias <u8vector> bitmap 
                              (* cnt (* (/ 1024 8) 256))
                              (* (+ cnt 1) (* (/ 1024 8) 256)))))
  (define (make-texture)
    (gl-clear GL_COLOR_BUFFER_BIT)
    (draw-source 0 '#u8(1 0 0))
    (draw-source 1 '#u8(0 1 0))
    (draw-source 2 '#u8(0 0 1))
    (gl-copy-tex-image-2d GL_TEXTURE_2D 0 GL_RGB 0 0 512 512 0))
  (define (accumulate)
    (gl-clear GL_COLOR_BUFFER_BIT)
    (gl-color 0 0 0)
    (gl-enable GL_TEXTURE_2D)
    (gl-draw-arrays GL_QUADS 0 (* 4 256))
    (gl-disable GL_TEXTURE_2D))

  (define (count)
    (let1 v (gl-read-pixels 0 0 32 32 GL_RGB GL_UNSIGNED_BYTE)
      (u8vector-dot *v1* v)))

  (make-texture)
  (accumulate)
  (until (gl-get-error) (pa$ = GL_NO_ERROR)
         => err (print "glError: "(glu-error-string err)))
  (count))

(define (find-closest-pic vec pics)
  (values-ref 
   (fold2 (lambda (pic i minscore)
            (let1 score (count-pixels (u8vector-xor vec pic))
              (if (< score (cdr minscore))
                (values (+ i 1) (cons i score))
                (values (+ i 1) minscore))))
          0 '(0 . #i1/0) pics)
   1))

(define (doit)
  (print (time (find-closest-pic (car *vecs*) (cdr *vecs*))))
  (exit 0))

(define (main args)
  (glut-init args)
  (glut-init-display-mode (logior GLUT_SINGLE GLUT_RGB))
  (glut-init-window-size 512 512)
  (glut-create-window (car args))

  (gl-pixel-store GL_UNPACK_ALIGNMENT 1)
  (gl-clear-color 0 0 0 0)
  (gl-viewport 0 0 512 512)
  (gl-matrix-mode GL_PROJECTION)
  (glu-ortho-2d 0 512 0 512)
  (gl-matrix-mode GL_MODELVIEW)
  (gl-load-identity)
  (gl-enable GL_BLEND)
  (gl-blend-func GL_ONE GL_ONE)
  (gl-shade-model GL_FLAT)
  (set! *texname* (ref (gl-gen-textures 1) 0))
  (gl-bind-texture GL_TEXTURE_2D *texname*)
  (gl-tex-parameter GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST)
  (gl-tex-parameter GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST)
  (gl-tex-env GL_TEXTURE_ENV GL_TEXTURE_ENV_MODE GL_ADD)
  (gl-interleaved-arrays GL_T2F_V3F *varray*)

  (glut-display-func doit)
  (glut-main-loop)
  0)

;;;
;;; test data generation
;;;
(use srfi-27)

(define (generate-random-pics n)
  (list-ec (: k n)
           (let1 v (make-u8vector (/ (* 1024 768) 8))
             (do-ec (: i (/ (* 1024 768) 8))
                    (u8vector-set! v i (random-integer (expt 2 8))))
             v)))

(define *vecs* (generate-random-pics 100))

Index

Feed

Other

Link

Pathtraq

loading...