Codes of Richardson Lucy Algorithm
Reading The Pixel Values:
> library(pixmap)
> lena <- read.pnm("lenna_blur.pgm")
> write.table(lena@grey,"mylenna", quote=FALSE, row.names = FALSE, col.names= FALSE)
C Code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define H 7
#define PIX 512
#define NUM 512 * 512
#define SIGMA 10
#ifndef max
#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
#endif
#ifndef min
#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
#endif
void dataread(float *y);
int distance(int i, int j, int k, int l);
void lambda(float *y, float *lold, float *lnew, float *p);
void renew(float *lold,float *lnew);
void spread(float *p);
void datasave(float *l);
int main(void){
int i;
float *y, *lold, *lnew, *p, ttt;
y = malloc(NUM * sizeof(float));
lold = malloc(NUM * sizeof(float));
lnew = malloc(NUM * sizeof(float));
p = malloc((2 * (H + 1) * (H + 1)) * sizeof(float));
spread(p);
dataread(y);
dataread(lold);
for(i = 0; i < 100; i++){
lambda(y, lold, lnew, p);
renew(lold, lnew);
printf("%d \n",i);
}
datasave(lnew);
free(p);
free(y);
free(lnew);
free(lold);
return 0;
}
/*READING THE DATA*/
void dataread(float *y){
int i;
FILE *fp;
fp = fopen("mylenna","r");
for(i = 0; i < NUM; i++){
fscanf(fp,"%f ",&y[i]);
}
return;
}
/*DEFINING A NORM*/
int distance(int i, int j, int k, int l){
int d;
d = (i - k) * (i - k) + (j - l) * (j - l);
return d;
}
/*LAMBDA VECTOR*/
void lambda(float *y, float *lold, float *lnew, float *p){
int i1, i2, j1, j2, k1, k2;
float temp, tmp;
for(i1 = 0; i1 < PIX; i1++){
for(i2 = 0; i2 < PIX; i2++){
tmp = 0;
for(j1 = max(0, i1 - H + 1); j1 < min(i1 + H - 1, PIX); j1++){
for(j2 = max(0, i2 - H + 1); j2 < min(i2 + H - 1, PIX); j2++){
temp = 0;
for(k1 = max(0, i1 - H + 1); k1 < min(i1 + H - 1, PIX); k1++){
for(k2 = max(0, i2 - H + 1); k2 < min(i2 + H - 1, PIX); k2++){
temp = temp + lold[k1 * PIX + k2] * p[distance(j1,j2,k1,k2)];
}
}
tmp = tmp + y[j1 * PIX + j2] * (p[distance(j1,j2,i1,i2)])/temp;
}
}
lnew[i1 * PIX + i2] = lold[i1 * PIX + i2] * tmp;
}
}
return;
}
/*Point Spread Function*/
void spread(float *p){
int i, j;
float temp = 0;
for(i = -H; i <= H; i++){
for(j = -H; j <= H; j++){
p[i * i + j * j] = exp(-((float)(i * i + j * j))/SIGMA);
temp += p[i * i + j * j];
}
}
for(i = -H; i <= H; i++)
for(j = -H; j <= H; j++)
p[i * i + j * j] = p[i * i + j * j]/temp;
return;
}
/*RENEW THE VALUE OF LAMBDA VECTOR*/
void renew(float *lold,float *lnew){
int i;
for(i = 0; i < NUM; i++)
lold[i] = lnew[i];
return;
}
/*SAVING THE DATA*/
void datasave(float *l){
int i, j;
FILE *fp;
fp = fopen("mylenn","w");
for(i = 0; i < PIX; i++){
for(j = 0; j < PIX; j++){
fprintf(fp,"%f ",l[i * PIX + j]);
}
fprintf(fp,"\n");
}
return;
}
Map of New Pixels
> plot(pixmapGrey(as.matrix(read.table("mylenn"))))
Interface Between R and C:
#include <R.h>
#include <Rdefines.h>
#include <Rinternals.h>
#include <stdlib.h>
#define H 7
#define PIX 512
#define NUM 512 * 512
#define SIGMA 10
#ifndef max
#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
#endif
#ifndef min
#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
#endif
int distance(int i, int j, int k, int l);
void lambda(double *y, double *lold, double *lnew, double *p);
void renew(double *lold,double *lnew);
void spread(double *p);
SEXP lenna(SEXP data)
{
int i;
double *y, *lold, *lnew, *p;
SEXP ans;
ans = PROTECT(NEW_NUMERIC(NUM));
double *z = NUMERIC_POINTER(ans);
y = malloc(NUM * sizeof(double));
lold = malloc(NUM * sizeof(double));
lnew = malloc(NUM * sizeof(double));
p = malloc((2 * (H + 1) * (H + 1)) * sizeof(double));
for(i = 0; i < NUM; i++){
y[i] = NUMERIC_POINTER(data)[i];
lold[i] = y[i];
}
spread(p);
for(i = 0; i < 100; i++){
lambda(y, lold, lnew, p);
renew(lold, lnew);
/* printf("%d \n",i); */
}
/* datasave(lnew); */
for(i = 0; i < NUM; i++)
z[i] = lnew[i];
free(p);
free(y);
free(lnew);
free(lold);
UNPROTECT(1);
return ans;
}
/*DEFINING A NORM*/
int distance(int i, int j, int k, int l){
int d;
d = (i - k) * (i - k) + (j - l) * (j - l);
return d;
}
/*LAMBDA VECTOR*/
void lambda(double *y, double *lold, double *lnew, double *p){
int i1, i2, j1, j2, k1, k2;
double temp, tmp;
for(i1 = 0; i1 < PIX; i1++){
for(i2 = 0; i2 < PIX; i2++){
tmp = 0;
for(j1 = max(0, i1 - H + 1); j1 < min(i1 + H - 1, PIX); j1++){
for(j2 = max(0, i2 - H + 1); j2 < min(i2 + H - 1, PIX); j2++){
temp = 0;
for(k1 = max(0, i1 - H + 1); k1 < min(i1 + H - 1, PIX); k1++){
for(k2 = max(0, i2 - H + 1); k2 < min(i2 + H - 1, PIX); k2++){
temp = temp + lold[k1 * PIX + k2] * p[distance(j1,j2,k1,k2)];
}
}
tmp = tmp + y[j1 * PIX + j2] * (p[distance(j1,j2,i1,i2)])/temp;
}
}
lnew[i1 * PIX + i2] = lold[i1 * PIX + i2] * tmp;
}
}
return;
}
void spread(double *p){
int i, j;
double temp = 0;
for(i = -H; i <= H; i++){
for(j = -H; j <= H; j++){
p[i * i + j * j] = exp(-((double)(i * i + j * j))/SIGMA);
temp += p[i * i + j * j];
}
}
for(i = -H; i <= H; i++)
for(j = -H; j <= H; j++)
p[i * i + j * j] = p[i * i + j * j]/temp;
return;
}
/*RENEW THE VALUE OF LAMBDA VECTOR*/
void renew(double *lold,double *lnew){
int i;
for(i = 0; i < NUM; i++)
lold[i] = lnew[i];
return;
}
Last modified: Sun Oct 31 21:03:43 IST 2010