Nothing
# Multiple Images Class
#
# Author: Allison Irvine, Tan Dang
setClass (
Class = "MultiIm",
representation = representation(
imageList= "list",
dimension= "numeric",
polynomials = "list",
storePoly = "logical",
momentType = "character",
order = "numeric",
Params = "list",
moments = "list",
reconstruction = "list",
invariant = "list",
error = "character"
)
)
# initialize method, called when a new object is created
# compute necessary thing, and compute moment
setMethod(
f="initialize",
signature="MultiIm",
definition = function(.Object,images) {
checkSize(.Object)=images;
.Object@storePoly= FALSE;
return(.Object)
}
)
# Generics for checkSize method
setGeneric (
name= "checkSize<-",
def=function(obj,value) standardGeneric("checkSize<-"),
)
# Method to check all images are of the same size
setReplaceMethod (
f="checkSize",
signature=c("MultiIm"),
definition = function(obj,value){
images= value;
check=TRUE;
images=lapply(images, function(z){
if (length(dim(z))>2) {
return(1/3*(z[,,1]+z[,,2]+z[,,3]))
} else {
return(z)
}
})
d=dim(images[[1]]);
noUse=lapply(images,function(z){
if (sum(dim(z)!=d)>0) check <<-FALSE; # The <<- assign is needed
});
if (!check) {
obj@error[length(obj@error)+1] = "Matrices are not of same size"
return(obj);
}
obj@imageList=images;
obj@dimension=dim(images[[1]]);
return(obj)
}
)
# Method to check if moment type is supported
setReplaceMethod (
f="momentType",
signature=c("MultiIm"),
definition = function(obj,value){
type=tolower(as.character(value));
if (length(type)==2){ #bivariate polynomials
if ((sum(type[[1]] == c("cheby","krawt","hahn")) + sum(type[[2]] == c("cheby","krawt","hahn")))==2
|| (sum(type[[1]] == c("gegen","chebycont","legend")) + sum(type[[2]] == c("gegen","chebycont","legend")))==2){
obj@momentType=c(type[[1]], type[[2]]);
} else {
obj@error[length(obj@error)+1]="This combination of moment types is not supported";
}
} else if (length(type)==1){
if (sum(type==c("gpzm", "fm", "fc", "fr"))==1){
obj@momentType=type;
} else if (sum(type==c("krawt", "cheby", "hahn", "chebycont","gegen","legend"))==1){
obj@momentType=c(type, type);
} else {
obj@error[length(obj@error)+1]="The specified moment type is not supported";
}
} else {
obj@error[length(obj@error)+1]="The specified moment type is not supported";
}
return(obj)
}
)
# Method to set order
setReplaceMethod(
f="setOrder",
signature=c("MultiIm"),
definition= function(obj, value) {
if (length(obj@momentType)==2){ #2 moment types
if (length(value)==2){
obj@order= as.integer(value);
} else if (length(value)==1) {
obj@order= c(as.integer(value), as.integer(value))
} else {
obj@error[length(obj@error)+1] = "Orders specified incorrectly - specify 1 or 2 orders";
}
} else if (length(obj@momentType)==1) {
if (sum(obj@momentType==c("fm", "fc", "fr"))==1){
if (length(value)==2){
obj@order= as.integer(value);
} else {
obj@error[length(obj@error)+1] = "This moment type requires 2 values: order and repetiton";
}
} else if (obj@momentType=="gpzm"){
if (length(value)==1){
obj@order= as.integer(value);
} else {
obj@error[length(obj@error)+1] = "The moment type requires 1 order";
}
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
# Method to check necessary Paramsater for each moment type
setReplaceMethod(
f="setParams",
signature=c("MultiIm"),
definition = function(obj,value){
if (length(obj@momentType)==2){ # real orthogonal moments
if ((length(value)==1) || (length(value)==2)){
param = list(NULL,NULL);
for (i in 1:length(value)){
if (obj@momentType[[i]]=="hahn"){
if (length(value[[i]])==2){
param[[i]]= as.numeric(c(value[[i]][[1]], value[[i]][[2]]));
} else {
obj@error[length(obj@error)+1] = "Hahn polynomials require 2 parameters: a, c";
}
} else if (sum(obj@momentType[[i]]==c("krawt", "gegen"))==1){
if (length(value[[i]])==1) {
param[[i]]= as.numeric(value[[i]][[1]])
} else {
obj@error[length(obj@error)+1] = paste(obj@momentType[[i]], "requires 1 parameter")
}
}
}
obj@Params= param;
}else {
obj@error[length(obj@error)+1] = "Parameters incorrectly specified";
return(obj)
}
} else if (length(obj@momentType)==1) { #complex moments
if (obj@momentType=="gpzm"){
a=as.integer(value);
if (length(a)==1){
obj@Params=list(a);
} else {
obj@error[length(obj@error)+1] = "Generalized Pseudo-Zernike polynomials require 1 parameter";
}
} else if (sum(obj@momentType==c("fm", "fc", "fr"))==1){
obj@Params=list(NULL)
obj@error[length(obj@error)+1] = "The specified moment type does not require a parameter";
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
# Generics for setPoly method
setGeneric (
name= "setPoly<-",
def=function(obj,value) standardGeneric("setPoly<-"),
)
# Method to compute polynomials of real orthogonal moment types
setReplaceMethod (
f="setPoly",
signature=c("MultiIm"),
definition = function(obj,value){
if (length(obj@momentType)==2){
obj@polynomials= OrthPolynomials(obj@momentType,obj@dimension,obj@order,obj@Params);
} else if (length(obj@momentType)==1){
obj@error[length(obj@error)+1] = "This method only available for OrthIm moment types"
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
# Method to compute moment
setReplaceMethod (
f="Moments",
signature=c("MultiIm"),
definition = function(obj,value){
if (length(obj@momentType)==2){ #real orthogonal moment types
setPoly(obj)=0;
xyMat= obj@polynomials;
xMat=xyMat[[1]];
yMat=xyMat[[2]];
obj@moments= lapply(obj@imageList,function(z){
return(t(yMat)%*%z%*%xMat)
});
} else if (length(obj@momentType)==1){ #complex moment types
I=array(1, c(obj@dimension[1],obj@dimension[2]))
# Assume centroid at center of image
x0 = (obj@dimension[2]+1)/2;
y0 = (obj@dimension[1]+1)/2;
radiusTheta=polarXY(I, c(x0,y0));
# Get radius and theta
radius= radiusTheta[[1]];
theta= radiusTheta[[2]];
if (obj@momentType=="gpzm"){
order= obj@order;
a = obj@Params[[1]];
temp= GPZMmultiple(obj@imageList,radius,theta,order,a, obj@storePoly);
obj@moments= temp[[1]];
obj@polynomials= list(temp[[2]]);
} else if (sum(obj@momentType==c("fc","fr", "fm"))) {
nmax=obj@order[1];
mmax=obj@order[2];
temp=Cmplxmultiple(obj@momentType,obj@imageList, radius,theta,nmax,mmax, obj@storePoly);
obj@moments= temp[[1]];
obj@polynomials= list(temp[[2]]);
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
# Method to reconstruct images
setReplaceMethod (
f="Reconstruct",
signature= c("MultiIm"),
definition = function(obj,value){
#if no maximum order given for reconstruction, use maximum available (not nan or inf)
order = checkOrder(obj@moments[[1]]);
#if order defined, check values
if(!is.null(value)) {
#check that user-defined order is valid
if(value[1]>order[1]) {
obj@error[length(obj@error)+1] = sprintf("maximum order in x direction is %d. Order is being reset to this value.",order[1])
value[1] = order[1]
}
if(obj@momentType[1]!="gpzm") {
if((length(value)==2) && (value[2]>order[2])) {
obj@error[length(obj@error)+1] = sprintf("maximum order in y direction is %d. Order is being reset to this value.",order[2])
value[2] = order[2]
} else if ((length(value)!=2)) {
value[2] = order[2]
}
}
order=value
}
if (length(obj@momentType)==2){
obj@reconstruction= lapply(obj@moments, function(z){
OrthReconstruct(z, obj@polynomials, obj@dimension, order)
});
} else if (length(obj@momentType)==1) {
# Assume centroid at center of image
x0 = (obj@dimension[2]+1)/2;
y0 = (obj@dimension[1]+1)/2;
I=array(1, c(obj@dimension[1],obj@dimension[2]))
radiusTheta=polarXY(I, c(x0,y0));
radius= radiusTheta[[1]];
theta= radiusTheta[[2]];
if (obj@momentType=="gpzm"){
obj@reconstruction= GPZMreconMulti(obj@moments, radius, theta, order[1], obj@Params[[1]]);
} else if (sum(obj@momentType==c("fc","fr", "fm"))) {
obj@reconstruction= CmplxreconMulti(obj@momentType, obj@moments, radius, theta, order[1], order[2]);
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
setReplaceMethod (
f="Invariant",
signature= c("MultiIm"),
definition = function(obj, value){
#for complex moment types
if (length(obj@momentType)==1){
if (sum(obj@momentType==c("gpzm","fc","fr","fm"))==1){
if (length(obj@imageList)!= length(obj@moments)){
Moments(obj)=NULL;
}
obj@invariant= lapply(obj@moments, function(z) {
z=abs(z);
return(z/z[1,1])});
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
} else if (length(obj@momentType)==2) { #for orthogonal types
storeObj= obj;
transform(obj)= value;
Moments(obj)= NULL;
storeObj@invariant= obj@moments;
obj= storeObj;
} else {
obj@error[length(obj@error)+1] = "A valid moment type must be specified";
}
return(obj)
}
)
setMethod(
f="plotPoly",
signature=c("MultiIm","Numbers"),
definition = function(obj,order) {
if (length(dim(order))<2){
obj@error[length(obj@error)+1] = "Please specify order and repetition to plot"
return(obj)
}
if ((dim(order)[1]<1)||(dim(order)[2]!=2)) {
obj@error[length(obj@error)+1] = "Please specify order and repetition to plot"
return(obj)
}
levels = seq(0,1,.000001);
g = gray(levels);
num = dim(order)[1];
order[,1] = order[,1]+1;
order[,2] = order[,2]+1;
if (length(obj@momentType)==1){
if (!(obj@storePoly)) {
obj@error[length(obj@error)+1] = "obj@storePoly is FALSE. Polynomial may not be stored.";
return(obj);
}
if (num<4) {
par(mfrow=c(1,num),xaxt="n",yaxt="n");
} else {
par(mfrow=c(floor(sqrt(num)), ceiling(sqrt(num))),xaxt="n",yaxt="n");
}
for (i in 1:num){
image(asinh(Re(obj@polynomials[[1]][,,order[i,1], order[i,2]])), col=g);
title(paste("Order", order[i,1]-1, ",Repetition", order[i,2]-1,sep=" "));
}
} else {
if (num<4) {
par(mfrow=c(1,num),xaxt="n",yaxt="n");
} else {
par(mfrow=c(floor(sqrt(num)), ceiling(sqrt(num))),xaxt="n",yaxt="n");
}
for (i in 1:num){
image(asinh(Re(obj@polynomials[[2]][, order[i,2] +1]%*%t(obj@polynomials[[1]][, order[i,1]+1]))), col=g);
title(paste("Order in X: ", order[i,1]-1, ",Order in Y: ", order[i,2]-1,sep=" "));
}
}
}
)
setMethod(
f="plotMoment",
signature=c("MultiIm"),
definition = function(obj){
num = length(obj@moments);
par(mfrow=c(ceiling(sqrt(num)), num%/%ceiling(sqrt(num))),xaxt="n",yaxt="n");
for (i in 1:num){
obj@moments[[i]] -> M;
if (is.complex(M)) M = abs(M);
image(asinh(M));
}
}
)
setReplaceMethod(
f="transform",
signature=c("MultiIm"),
definition = function(obj, value){
if (is.null(value) || value<1){
obj@error[length(obj@error)+1] = "Resolution must be an natural number >0";
return(obj)
}
resolution= as.integer(value);
if (length(value)==1){
checkSize(obj)= lapply(obj@imageList, function(z){
return(polarTransform(z, resolution,,calcCentroid(z))[[1]])
})
} else {
scale= as.integer(value[[2]]);
if (scale<=1){
obj@error[length(obj@error)+1] = "Scale must be an integer >1";
return(obj)
}
checkSize(obj)= lapply(obj@imageList, function(z){
return(polarTransform(z, resolution, scale,calcCentroid(z))[[1]])
})
}
return(obj)
}
)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.