Skip to content

Commit

Permalink
0.20210502: BiCubic interpolation and margin
Browse files Browse the repository at this point in the history
  • Loading branch information
zvezdochiot committed May 2, 2021
1 parent 2121c59 commit 118ab67
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 51 deletions.
4 changes: 3 additions & 1 deletion BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# GeoConformImage
# 0.20210323
# 0.20210502

Download
--------
Expand All @@ -14,6 +14,8 @@ Depends this library:

freeimage

For Windows: copy `FreeImage.dll` in project and `FreeImage.lib` + `FreeImage.h` in `src` project.

Build
-----

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

----------------------------------------------------------------

0.20210502

Stable: BiCubic interpolation and margin

0.20210414

FreeImage: fix ImthresholdGenericLoader
Expand Down
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@ PROGNAME = $(PNAME)
CC = gcc
CPP = g++
CFLAGS = -Isrc -DUNIX -O2 -Wall -s
SRCS = src
VER = 0
VERB = 20210414
VERB = 20210502
ifeq ($(OS),Windows_NT)
LIBS = FreeImage.lib
LIBS = $(SRCS)/FreeImage.lib
PLIBF = $(PNAME).$(VER).dll
PLIBFI = $(PNAME)freeimage.$(VER).dll
RM = del /Q
else
LIBS = -lfreeimage
PLIBF = lib$(PNAME).so.$(VER)
PLIBFI = lib$(PNAME)freeimage.so.$(VER)
RM = rm -f
endif
PLIB = $(PLIBF) $(PLIBFI)
PREFIX = /usr/local
DOCPREFIX = $(PREFIX)/share/doc/$(PNAME)
SRCS = src
INSTALL = install
LN = ln -fs
RM = rm -f

.PHONY: all clean install

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ geoconformimage [options] <input_image> <output_image>

```sh
-i N iteration set (default = 10)
-m N margin (default = 0)
-p str string conform params: "A0,B0,A1,B1,[...,A9,B9]"
-r str string region image: "Xws,Yws,Xne,Yne"
-h this help
Expand Down Expand Up @@ -57,7 +58,7 @@ Output= world-rus.jpg.out.png

## Copyright

Public Domain Mark 1.0
Public Domain Mark 1.0
No Copyright


Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.20210414
0.20210502
5 changes: 4 additions & 1 deletion man/man1/geoconformimage.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH "GeoConformImage" 1 0.20210325 "25 Mar 2021" "User Manual"
.TH "GeoConformImage" 1 0.20210502 "2 May 2021" "User Manual"

.SH NAME
geoconformimage
Expand All @@ -14,6 +14,9 @@ geoconformimage [options] <input_image> <output_image>
-i N
iteration set (default = 10)
.TP
-m N
margin (default = 0)
.TP
-p str
string conform params: "A0,B0,A1,B1,[...,A9,B9]"
.TP
Expand Down
124 changes: 84 additions & 40 deletions src/geoconform.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ IMTpixel IMTcalcS (IMTpixel im)
unsigned ims, d;

ims = 0;
for (d = 0; d < 3; d++)
for (d = 0; d < COUNTC; d++)
{
ims += (unsigned)im.c[d];
}
Expand All @@ -81,8 +81,8 @@ IMTimage IMTalloc (IMTsize size, int bs)
}
im.size.height = size.height;
im.size.width = size.width;
im.bits += 24;
bs -= 24;
im.bits += COUNTC * 8;
bs -= COUNTC * 8;
}
if (bs > 0)
{
Expand Down Expand Up @@ -112,7 +112,7 @@ IMTimage IMTfree (IMTimage im)
free(im.p[y]);
}
free(im.p);
im.bits -= 24;
im.bits -= COUNTC * 8;
}
if (im.bits > 0)
{
Expand All @@ -129,46 +129,82 @@ IMTimage IMTfree (IMTimage im)

////////////////////////////////////////////////////////////////////////////////

IMTpixel IMTinterpolation (IMTimage p_im, GCIcoord p)
IMTpixel IMTInterpolateBiCubic (IMTimage p_im, GCIcoord p)
{
unsigned d, y1, x1, y2, x2;
float p11, p21, p12, p22, ky, kx, k11, k21, k12, k22, t;
int i, d, xi, yi, xf, yf;
float d0, d2, d3, a0, a1, a2, a3;
float x, y, dx, dy;
float Cc, C[4];
IMTpixel res;

y1 = IndexClamp((int)p.x, (p_im.size.height - 1));
x1 = IndexClamp((int)p.y, (p_im.size.width - 1));
y2 = IndexClamp((int)(y1 + 1), (p_im.size.height - 1));
x2 = IndexClamp((int)(x1 + 1), (p_im.size.width - 1));
ky = p.x - y1;
if (ky < 0)
y = p.x;
x = p.y;
yi = IndexClamp((int)y, (p_im.size.height - 1));
xi = IndexClamp((int)x, (p_im.size.width - 1));
dy = y - yi;
dx = x - xi;
for(d = 0; d < COUNTC; d++)
{
ky = 0.0;
}
if (ky > 1)
{
ky = 1.0;
}
kx = p.y - x1;
if (kx < 0)
{
kx = 0.0;
}
if (kx > 1)
{
kx = 1.0;
for(i = -1; i < 3; i++)
{
yf = IndexClamp((int)(y + i), (p_im.size.height - 1));
xf = IndexClamp((int)x, (p_im.size.width - 1));
a0 = p_im.p[yf][xf].c[d];
xf = IndexClamp((int)(x - 1), (p_im.size.width - 1));
d0 = p_im.p[yf][xf].c[d];
d0 -= a0;
xf = IndexClamp((int)(x + 1), (p_im.size.width - 1));
d2 = p_im.p[yf][xf].c[d];
d2 -= a0;
xf = IndexClamp((int)(x + 2), (p_im.size.width - 1));
d3 = p_im.p[yf][xf].c[d];
d3 -= a0;
a1 = -1.0f / 3.0f * d0 + d2 - 1.0f / 6.0f * d3;
a2 = 1.0f / 2.0f * d0 + 1.0f / 2.0f * d2;
a3 = -1.0f / 6.0 * d0 - 1.0f / 2.0f * d2 + 1.0f / 6.0f * d3;
C[i + 1] = a0 + (a1 + (a2 + a3 * dx) * dx) * dx;
}
d0 = C[0] - C[1];
d2 = C[2] - C[1];
d3 = C[3] - C[1];
a0 = C[1];
a1 = -1.0f / 3.0f * d0 + d2 - 1.0f / 6.0f * d3;
a2 = 1.0f / 2.0f * d0 + 1.0f / 2.0f * d2;
a3 = -1.0f / 6.0f * d0 - 1.0f / 2.0f * d2 + 1.0f / 6.0f * d3;
Cc = a0 + (a1 + (a2 + a3 * dy) * dy) * dy;
res.c[d] = ByteClamp((int)(Cc + 0.5f));
}
k11 = (1.0 - ky) * (1.0 - kx);
k21 = ky * (1.0 - kx);
k12 = (1.0 - ky) * kx;
k22 = ky * kx;
for (d = 0; d < 3; d++)
res = IMTcalcS (res);

return res;
}

////////////////////////////////////////////////////////////////////////////////

IMTpixel IMTInterpolateBiLine (IMTimage p_im, GCIcoord p)
{
int d, xi, yi, xf, yf;
float x, y, dx1, dy1, dx2, dy2;
float p11, p12, p21, p22;
IMTpixel res;

y = p.x;
x = p.y;
yi = IndexClamp((int)y, (p_im.size.height - 1));
xi = IndexClamp((int)x, (p_im.size.width - 1));
dy1 = y - yi;
dx1 = x - xi;
dy2 = 1.0f - dy1;
dx2 = 1.0f - dx1;
yf = IndexClamp((int)(y + 1), (p_im.size.height - 1));
xf = IndexClamp((int)(x + 1), (p_im.size.width - 1));
for (d = 0; d < COUNTC; d++)
{
p11 = (float)p_im.p[y1][x1].c[d];
p21 = (float)p_im.p[y2][x1].c[d];
p12 = (float)p_im.p[y1][x2].c[d];
p22 = (float)p_im.p[y2][x2].c[d];
t = p11 * k11 + p21 * k21 + p12 * k12 + p22 * k22;
res.c[d] = ByteClamp((int)(t + 0.5));
p11 = p_im.p[yi][xi].c[d];
p12 = p_im.p[yi][xf].c[d];
p21 = p_im.p[yf][xi].c[d];
p22 = p_im.p[yf][xf].c[d];
res.c[d] = ByteClamp((int)(dy2 * (dx2 * p11 + dx1 * p12) + dy1 * (dx2 * p21 + dx1 * p22) + 0.5f));
}
res = IMTcalcS (res);

Expand Down Expand Up @@ -272,7 +308,7 @@ GCIparams GCIcalcallparams(GCIparams params)
int h, w;
GCIcoord cmin1, cmax1, cmean1, cd1;
GCIcoord cmin2, cmax2, cmean2, cd2;
float areai, areac, aream;
float areai, areac, aream, margin;

params.rect1.p[1].x = params.rect1.p[0].x;
params.rect1.p[1].y = params.rect1.p[2].y;
Expand Down Expand Up @@ -340,6 +376,11 @@ GCIparams GCIcalcallparams(GCIparams params)
}
cmean2.x *= 0.25f;
cmean2.y *= 0.25f;
margin = (float)params.margin * params.mi;
cmin2.x -= margin;
cmin2.y -= margin;
cmax2.x += margin;
cmax2.y += margin;
cd2.x = cmax2.x - cmin2.x;
cd2.y = cmax2.y - cmin2.y;
params.rect2.min = cmin2;
Expand Down Expand Up @@ -375,13 +416,16 @@ IMTimage IMTFilterGeoConform (IMTimage p_im, IMTimage d_im, GCIparams params)
cf.y -= params.rect1.min.y;
cf.x *= params.m;
cf.y *= params.m;
cf.x -= 0.5f;
cf.y -= 0.5f;
if (cf.x < 0 || cf.y < 0 || cf.x >= params.size1.height || cf.y >= params.size1.width)
{
d_im.p[i][j] = IMTset(0, 0, 0);
}
else
{
d_im.p[i][j] = IMTinterpolation(p_im, cf);
// d_im.p[i][j] = IMTInterpolateBiLine(p_im, cf);
d_im.p[i][j] = IMTInterpolateBiCubic(p_im, cf);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/geoconform.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern "C" {
#define COUNTA 20
#define COUNTC 3
#define COUNTG 10
#define COUNTM 0

typedef uint8_t BYTE;
typedef uint16_t WORD;
Expand Down Expand Up @@ -96,6 +97,7 @@ extern "C" {
GCIrect rect1, rect2;
float m, mi;
int iters;
int margin;
}
GCIparams;

Expand All @@ -108,7 +110,8 @@ extern "C" {
IMTpixel IMTcalcS (IMTpixel);
IMTimage IMTalloc (IMTsize, int);
IMTimage IMTfree (IMTimage);
IMTpixel IMTinterpolation (IMTimage, GCIcoord);
IMTpixel IMTInterpolateBiCubic (IMTimage, GCIcoord);
IMTpixel IMTInterpolateBiLine (IMTimage, GCIcoord);
GCIcoord GCIconformaltrans(GCIctrans, GCIcoord);
GCIparams GCIcalcallparams(GCIparams);
IMTimage IMTFilterGeoConform (IMTimage, IMTimage, GCIparams);
Expand Down
9 changes: 8 additions & 1 deletion src/geoconformimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void GeoConformImageUsage(const char *progname)
printf("Usage : %s [options] <input_image> <output_image>\n", progname);
printf("options:\n");
printf(" -i N iteration set (default = %d)\n", COUNTG);
printf(" -m N margin (default = %d)\n", COUNTM);
printf(" -p str string conform params: \"A0,B0,A1,B1,[...,A9,B9]\"\n");
printf(" -r str string region image: \"Xws,Yws,Xne,Yne\"\n");
printf(" -h this help\n");
Expand All @@ -47,10 +48,11 @@ int main(int argc, char *argv[])
IMTimage imgin, imgout;
bool fhelp = false;
params.iters = COUNTG;
params.margin = COUNTM;

GeoConformImageTitle();

while ((opt = getopt(argc, argv, ":i:p:r:h")) != -1)
while ((opt = getopt(argc, argv, ":i:m:p:r:h")) != -1)
{
switch(opt)
{
Expand All @@ -59,6 +61,11 @@ int main(int argc, char *argv[])
if (params.iters < 2) params.iters = 2;
printf("Parameter iters set %d.\n", params.iters);
break;
case 'm':
params.margin = atoi(optarg);
if (params.margin < 0) params.margin = 0;
printf("Parameter margin set %d.\n", params.margin);
break;
case 'p':
params.trans.na = sscanf(optarg, "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", &params.trans.a[0], &params.trans.a[1], &params.trans.a[2], &params.trans.a[3], &params.trans.a[4], &params.trans.a[5], &params.trans.a[6], &params.trans.a[7], &params.trans.a[8], &params.trans.a[9], &params.trans.a[10], &params.trans.a[11], &params.trans.a[12], &params.trans.a[13], &params.trans.a[14], &params.trans.a[15], &params.trans.a[16], &params.trans.a[17], &params.trans.a[18], &params.trans.a[19]);
if (params.trans.na < 3)
Expand Down

0 comments on commit 118ab67

Please sign in to comment.