Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Added resampling primitives. Up- and downsampling, interpolation and decimation. The latter two are done at the Tcl level for the moment. That is inefficient and future work should replace them with C level primitives which integrate the up/down sampling with the proper filtering. Added associated demos. |
|---|---|
| Timelines: | family | ancestors | descendants | both | ak-experimental |
| Files: | files | file ages | folders |
| SHA1: |
97dd176de77ab5d9e15865e66043702e |
| User & Date: | andreask 2010-07-27 05:23:24.000 |
| Original Comment: | Added resampling primitives. Up- and downsampling, interpolation and decimation. The latter two are down at Tcl level for the moment. That is inefficient and future work should replace them with C level primitives which integrate the up/down sampling with the proper filtering. Added associated demos. |
Context
|
2010-07-27
| ||
| 21:38 | Added map tables for thesholding and (sampled) gaussian. Thresholding also got convenience commands for direct access. Added appropriate demos. check-in: dfcebdfb37 user: andreask tags: ak-experimental | |
| 05:23 | Added resampling primitives. Up- and downsampling, interpolation and decimation. The latter two are done at the Tcl level for the moment. That is inefficient and future work should replace them with C level primitives which integrate the up/down sampling with the proper filtering. Added associated demos. check-in: 97dd176de7 user: andreask tags: ak-experimental | |
|
2010-07-22
| ||
| 07:21 | Documentation. Started to document the "kernel ..." and "convolve" methods check-in: 738a10a619 user: andreask tags: ak-experimental | |
Changes
Changes to crimp_tcl.tcl.
| ︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
}
}
}
}
return [map_$type $image {*}$args]
}
proc ::crimp::split {image} {
set type [TypeOf $image]
if {![Has split_$type]} {
return -code error "Unable to split images of type \"$type\""
}
return [split_$type $image]
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
}
}
}
}
return [map_$type $image {*}$args]
}
proc ::crimp::downsample {image factor} {
set type [TypeOf $image]
set f downsample_$type
if {![Has $f]} {
return -code error "Unable to downsample images of type \"$type\""
}
return [$f $image $factor]
}
proc ::crimp::upsample {image factor} {
set type [TypeOf $image]
set f upsample_$type
if {![Has $f]} {
return -code error "Unable to upsample images of type \"$type\""
}
return [$f $image $factor]
}
proc ::crimp::decimate {image factor kernel} {
# Combines downsampling with a pre-processing step applying a
# low-pass filter to avoid aliasing of higher image frequencies.
# We assume that the low-pass filter is separable, and the kernel
# is the 1-D horizontal form of it. We compute the vertical form
# on our own, transposing the kernel.
# NOTE: This implementation, while easy conceptually, is not very
# efficient, because it does the filtering on the input image,
# before downsampling.
# FUTURE: Write C level primitive integrating filter and sampler,
# computing the filter only for the pixels which go into the
# result.
return [downsample \
[convolve $image $kernel [kernel transpose $kernel]] \
$factor]
}
proc ::crimp::interpolate {image factor kernel} {
# Combines upsampling with a post-processing step applying a
# low-pass filter to copies of the image at higher image
# frequencies.
# We assume that the low-pass filter is separable, and the kernel
# is the 1-D horizontal form of it. We compute the vertical form
# on our own, transposing the kernel.
# NOTE: This implementation, while easy conceptually, is not very
# efficient, because it does the filtering on the full output image,
# after upsampling.
# FUTURE: Write C level primitive integrating filter and sampler,
# computing the filter only for the actually new pixels, and use
# polyphase restructuring.
# DANGER: This assumes that the filter, applied to the original
# pixels leaves them untouched. I.e. scaled center weight is 1.
# The easy implementation here does not have this assumption.
return [convolve [upsample $image $factor] \
$kernel [kernel transpose $kernel]]
}
proc ::crimp::split {image} {
set type [TypeOf $image]
if {![Has split_$type]} {
return -code error "Unable to split images of type \"$type\""
}
return [split_$type $image]
|
| ︙ | ︙ | |||
665 666 667 668 669 670 671 672 673 674 675 676 677 678 |
namespace eval ::crimp {
namespace export type width height dimensions channels
namespace export read write convert join flip split table
namespace export invert solarize gamma degamma remap map
namespace export wavy psychedelia matrix blend over blank
namespace export setalpha histogram max min screen add
namespace export subtract difference multiply convolve
namespace export kernel expand
#
namespace ensemble create
}
# # ## ### ##### ######## #############
return
| > | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 |
namespace eval ::crimp {
namespace export type width height dimensions channels
namespace export read write convert join flip split table
namespace export invert solarize gamma degamma remap map
namespace export wavy psychedelia matrix blend over blank
namespace export setalpha histogram max min screen add
namespace export subtract difference multiply convolve
namespace export downsample upsample decimate interpolate
namespace export kernel expand
#
namespace ensemble create
}
# # ## ### ##### ######## #############
return
|
Added demos/convolve_pseudoedge.tcl.
> > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def op_convolve_pseudoedges {
label {Pseudo Edges}
setup {
variable K [crimp kernel make {
{1 2 4 2 1}
{2 4 8 4 2}
{4 8 16 8 4}
{2 4 8 4 2}
{1 2 4 2 1}}]
# Separable kernel, compute the horizontal and vertical kernels.
variable Kx [crimp kernel make {{1 2 4 2 1}}]
variable Ky [crimp kernel transpose $Kx]
}
setup_image {
# show_image [crimp convolve [base] $K]
# Separable kernel, convolve x and y separately. Same result
# as for the combined kernel, but faster.
set n [crimp add [base] [crimp difference [base] [crimp convolve [base] $Kx $Ky]]]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/decimate2.tcl.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 |
def op_decimate2 {
label Decimate\u21932
setup {
set K [crimp kernel make {{1 2 1}}]
}
setup_image {
set n [crimp decimate [base] 2 $K]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/decimate4.tcl.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 |
def op_decimate4 {
label Decimate\u21934
setup {
set K [crimp kernel make {{1 2 1}}]
}
setup_image {
set n [crimp decimate \
[crimp decimate [base] 2 $K] \
2 $K]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/decint.tcl.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def op_decint2 {
label "Decimate\u21932, Interpolate\u21912"
setup {
set KD [crimp kernel make {{1 2 1}}]
set KI [crimp kernel make {{1 2 1}} 2]
}
setup_image {
set n [crimp interpolate \
[crimp decimate [base] 2 $KD] \
2 $KI]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/downsample2.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_downsample2 {
label Downsample\u21932
setup_image {
show_image [crimp downsample [base] 2]
}
}
|
Added demos/downsample3.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_downsample3 {
label Downsample\u21933
setup_image {
show_image [crimp downsample [base] 3]
}
}
|
Added demos/downsample4.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_downsample4 {
label Downsample\u21934
setup_image {
show_image [crimp::downsample_rgba [base] 4]
}
}
|
Added demos/interpolate2.tcl.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 |
def op_interpolate2 {
label Interpolate\u21912
setup {
# Tent kernel.
set K [crimp kernel make {{1 2 1}} 2]
}
setup_image {
set n [crimp interpolate [base] 2 $K]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/interpolate4.tcl.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def op_interpolate4 {
label Interpolate\u21914
setup {
# Tent kernel.
set K [crimp kernel make {{1 2 1}} 2]
}
setup_image {
set n [crimp interpolate \
[crimp interpolate [base] 2 $K] \
2 $K]
set m [crimp blank grey8 {*}[crimp dimensions $n] 255]
show_image [crimp setalpha $n $m]
}
}
|
Added demos/upsample2.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_upsample2 {
label Upsample\u21912
setup_image {
show_image [crimp upsample [base] 2]
}
}
|
Added demos/upsample3.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_upsample3 {
label Upsample\u21913
setup_image {
show_image [crimp upsample [base] 3]
}
}
|
Added demos/upsample4.tcl.
> > > > > > | 1 2 3 4 5 6 |
def op_upsample4 {
label Upsample\u21914
setup_image {
show_image [crimp upsample [base] 4]
}
}
|
Added operator/downsample-grey8.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
downsample_grey8
Tcl_Obj* imageObj
int factor
/*
* The input image is downsampled by storing only every 'factor' pixel into
* the result. Note that this method of shrinking an image causes image
* frequencies above the nyquist threshold of the result to be aliased into
* the range.
*
* The input image has to be convolved with a low-pass filter first, to avoid
* such artefacts. The integrated combination of such a filter with
* downsampling is called 'decimation'. This is but one step in the generation
* of image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi;
crimp_input (imageObj, image, grey8);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w/factor, image->h/factor);
for (yo = 0, yi = 0; yo < result->h; yo++, yi += factor) {
for (xo = 0, xi = 0; xo < result->w; xo++, xi += factor) {
GREY8 (result, xo, yo) = GREY8 (image, xi, yi);
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/downsample-hsv.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
downsample_hsv
Tcl_Obj* imageObj
int factor
/*
* The input image is downsampled by storing only every 'factor' pixel into
* the result. Note that this method of shrinking an image causes image
* frequencies above the nyquist threshold of the result to be aliased into
* the range.
*
* The input image has to be convolved with a low-pass filter first, to avoid
* such artefacts. The integrated combination of such a filter with
* downsampling is called 'decimation'. This is but one step in the generation
* of image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi;
crimp_input (imageObj, image, hsv);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w/factor, image->h/factor);
for (yo = 0, yi = 0; yo < result->h; yo++, yi += factor) {
for (xo = 0, xi = 0; xo < result->w; xo++, xi += factor) {
H (result, xo, yo) = H (image, xi, yi);
S (result, xo, yo) = S (image, xi, yi);
V (result, xo, yo) = V (image, xi, yi);
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/downsample-rgb.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
downsample_rgb
Tcl_Obj* imageObj
int factor
/*
* The input image is downsampled by storing only every 'factor' pixel into
* the result. Note that this method of shrinking an image causes image
* frequencies above the nyquist threshold of the result to be aliased into
* the range.
*
* The input image has to be convolved with a low-pass filter first, to avoid
* such artefacts. The integrated combination of such a filter with
* downsampling is called 'decimation'. This is but one step in the generation
* of image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi;
crimp_input (imageObj, image, rgb);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w/factor, image->h/factor);
for (yo = 0, yi = 0; yo < result->h; yo++, yi += factor) {
for (xo = 0, xi = 0; xo < result->w; xo++, xi += factor) {
R (result, xo, yo) = R (image, xi, yi);
G (result, xo, yo) = G (image, xi, yi);
B (result, xo, yo) = B (image, xi, yi);
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/downsample-rgba.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
downsample_rgba
Tcl_Obj* imageObj
int factor
/*
* The input image is downsampled by storing only every 'factor' pixel into
* the result. Note that this method of shrinking an image causes image
* frequencies above the nyquist threshold of the result to be aliased into
* the range.
*
* The input image has to be convolved with a low-pass filter first, to avoid
* such artefacts. The integrated combination of such a filter with
* downsampling is called 'decimation'. This is but one step in the generation
* of image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi;
crimp_input (imageObj, image, rgba);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w/factor, image->h/factor);
for (yo = 0, yi = 0; yo < result->h; yo++, yi += factor) {
for (xo = 0, xi = 0; xo < result->w; xo++, xi += factor) {
R (result, xo, yo) = R (image, xi, yi);
G (result, xo, yo) = G (image, xi, yi);
B (result, xo, yo) = B (image, xi, yi);
A (result, xo, yo) = A (image, xi, yi);
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/upsample-grey8.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
upsample_grey8
Tcl_Obj* imageObj
int factor
/*
* The input image is upsampled by inserting 'factor-1' 0-pixels after every
* pixel of the input. Note that this method of expanding an image introduces
* copies of the input to appear at higher frequencies.
*
* The output image has to be convolved with a low-pass filter after expansion
* to avoid such artefacts. The integrated combination of upsampling and such
* a filter is called 'interpolation'. This is but one step in the generation
* of difference image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi, dx, dy;
crimp_input (imageObj, image, grey8);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w*factor, image->h*factor);
for (yo = 0, yi = 0; yi < image->h; yo += factor, yi ++) {
for (xo = 0, xi = 0; xi < image->w; xo += factor, xi ++) {
/* Copy the pixel */
GREY8 (result, xo, yo) = GREY8 (image, xi, yi);
/* And insert factor black (0) pixels after */
for (dx = 1; dx < factor; dx++) {
GREY8 (result, xo + dx, yo) = BLACK;
}
}
/* And insert factor black lines after the intput line*/
for (dy = 1; dy < factor; dy++) {
for (xo = 0; xo < result->w; xo++) {
GREY8 (result, xo, yo + dy) = BLACK;
}
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/upsample-hsv.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
upsample_hsv
Tcl_Obj* imageObj
int factor
/*
* The input image is upsampled by inserting 'factor-1' 0-pixels after every
* pixel of the input. Note that this method of expanding an image introduces
* copies of the input to appear at higher frequencies.
*
* The output image has to be convolved with a low-pass filter after expansion
* to avoid such artefacts. The integrated combination of upsampling and such
* a filter is called 'interpolation'. This is but one step in the generation
* of difference image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi, dx, dy;
crimp_input (imageObj, image, hsv);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w*factor, image->h*factor);
for (yo = 0, yi = 0; yi < image->h; yo += factor, yi ++) {
for (xo = 0, xi = 0; xi < image->w; xo += factor, xi ++) {
/* Copy the pixel */
H (result, xo, yo) = H (image, xi, yi);
S (result, xo, yo) = S (image, xi, yi);
V (result, xo, yo) = V (image, xi, yi);
/* And insert factor black (0) pixels after */
for (dx = 1; dx < factor; dx++) {
H (result, xo + dx, yo) = BLACK;
S (result, xo + dx, yo) = BLACK;
V (result, xo + dx, yo) = BLACK;
}
}
/* And insert factor black lines after the intput line*/
for (dy = 1; dy < factor; dy++) {
for (xo = 0; xo < result->w; xo++) {
H (result, xo, yo + dy) = BLACK;
S (result, xo, yo + dy) = BLACK;
V (result, xo, yo + dy) = BLACK;
}
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/upsample-rgb.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
upsample_rgb
Tcl_Obj* imageObj
int factor
/*
* The input image is upsampled by inserting 'factor-1' 0-pixels after every
* pixel of the input. Note that this method of expanding an image introduces
* copies of the input to appear at higher frequencies.
*
* The output image has to be convolved with a low-pass filter after expansion
* to avoid such artefacts. The integrated combination of upsampling and such
* a filter is called 'interpolation'. This is but one step in the generation
* of difference image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi, dx, dy;
crimp_input (imageObj, image, rgb);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w*factor, image->h*factor);
for (yo = 0, yi = 0; yi < image->h; yo += factor, yi ++) {
for (xo = 0, xi = 0; xi < image->w; xo += factor, xi ++) {
/* Copy the pixel */
R (result, xo, yo) = R (image, xi, yi);
G (result, xo, yo) = G (image, xi, yi);
B (result, xo, yo) = B (image, xi, yi);
/* And insert factor black (0) pixels after */
for (dx = 1; dx < factor; dx++) {
R (result, xo + dx, yo) = BLACK;
G (result, xo + dx, yo) = BLACK;
B (result, xo + dx, yo) = BLACK;
}
}
/* And insert factor black lines after the intput line*/
for (dy = 1; dy < factor; dy++) {
for (xo = 0; xo < result->w; xo++) {
R (result, xo, yo + dy) = BLACK;
G (result, xo, yo + dy) = BLACK;
B (result, xo, yo + dy) = BLACK;
}
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added operator/upsample-rgba.crimp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
upsample_rgba
Tcl_Obj* imageObj
int factor
/*
* The input image is upsampled by inserting 'factor-1' 0-pixels after every
* pixel of the input. Note that this method of expanding an image introduces
* copies of the input to appear at higher frequencies.
*
* The output image has to be convolved with a low-pass filter after expansion
* to avoid such artefacts. The integrated combination of upsampling and such
* a filter is called 'interpolation'. This is but one step in the generation
* of difference image pyramids.
*/
crimp_image* image;
crimp_image* result;
int xo, yo, xi, yi, dx, dy;
crimp_input (imageObj, image, rgba);
if (factor < 1) {
Tcl_SetResult(interp, "bad sampling factor, expected integer > 0", TCL_STATIC);
return TCL_ERROR;
}
if (factor == 1) {
Tcl_SetObjResult(interp, imageObj);
return TCL_OK;
}
result = crimp_new (image->itype, image->w*factor, image->h*factor);
for (yo = 0, yi = 0; yi < image->h; yo += factor, yi ++) {
for (xo = 0, xi = 0; xi < image->w; xo += factor, xi ++) {
/* Copy the pixel */
R (result, xo, yo) = R (image, xi, yi);
G (result, xo, yo) = G (image, xi, yi);
B (result, xo, yo) = B (image, xi, yi);
A (result, xo, yo) = A (image, xi, yi);
/* And insert factor black (0) pixels after */
for (dx = 1; dx < factor; dx++) {
R (result, xo + dx, yo) = BLACK;
G (result, xo + dx, yo) = BLACK;
B (result, xo + dx, yo) = BLACK;
A (result, xo + dx, yo) = OPAQUE;
}
}
/* And insert factor black lines after the intput line*/
for (dy = 1; dy < factor; dy++) {
for (xo = 0; xo < result->w; xo++) {
R (result, xo, yo + dy) = BLACK;
G (result, xo, yo + dy) = BLACK;
B (result, xo, yo + dy) = BLACK;
A (result, xo, yo + dy) = OPAQUE;
}
}
}
Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;
/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|