Image registration with SimpleITK - algorithm

I want to do multi-modality image registration(mri/ct) but I do not have completely aligned images, results obtained with simpleITK are very bad. Even if I try to align them, results are still ridiculously bad.
What can I do to fix this? My registration code is as follow:
import SimpleITK as sitk
def fusion(ct, mr):
fixed = sitk.GetImageFromArray(ct, isVector=True)
moving = sitk.GetImageFromArray(mr, isVector=True)
numberOfBins = 24
samplingPercentage = 0.10
R = sitk.ImageRegistrationMethod()
R.SetMetricAsMattesMutualInformation(numberOfBins)
R.SetMetricSamplingPercentage(samplingPercentage,sitk.sitkWallClock)
R.SetMetricSamplingStrategy(R.RANDOM)
R.SetOptimizerAsRegularStepGradientDescent(1.0,.001,200)
R.SetInitialTransform(sitk.TranslationTransform(fixed.GetDimension()))
R.SetInterpolator(sitk.sitkLinear)
#R.AddCommand( sitk.sitkIterationEvent, lambda: command_iteration(R) )
outTx = R.Execute(fixed, moving)
def get_result():
resampler = sitk.ResampleImageFilter()
resampler.SetReferenceImage(fixed);
resampler.SetInterpolator(sitk.sitkLinear)
resampler.SetDefaultPixelValue(100)
resampler.SetTransform(outTx)
out = resampler.Execute(moving)
simg1 = sitk.Cast(sitk.RescaleIntensity(fixed), sitk.sitkUInt8)
simg2 = sitk.Cast(sitk.RescaleIntensity(out), sitk.sitkUInt8)
cimg = sitk.Compose(simg1, simg2, simg1//2.+simg2//2.)
cimg = sitk.Compose(simg1, simg2, simg1//2.+simg2//2.)
return sitk.GetArrayFromImage(cimg)
#sitk.Show( cimg, "ImageRegi
return get_result()

I think you forgot to make an initial alignment of your images at the beginning.
trans = sitk.CenteredTransformInitializer(fixed ,moving, sitk.Euler3DTransform(), sitk.CenteredTransformInitializerFilter.GEOMETRY)

Related

Image will not display in tkinter [duplicate]

This code works:
import tkinter
root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root.mainloop()
It shows me the image.
Now, this code compiles but it doesn't show me the image, and I don't know why, because it's the same code, in a class:
import tkinter
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root = tkinter.Tk()
test = Test(root)
root.mainloop()
The variable photo is a local variable which gets garbage collected after the class is instantiated. Save a reference to the photo, for example:
self.photo = tkinter.PhotoImage(...)
If you do a Google search on "tkinter image doesn't display", the first result is this:
Why do my Tkinter images not appear? (The FAQ answer is currently not outdated)
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
def open_img():
global img
path = r"C:\.....\\"
img = ImageTk.PhotoImage(Image.open(path))
panel = Label(root, image=img)
panel.pack(side="bottom", fill="both")
but1 = Button(root, text="click to get the image", command=open_img)
but1.pack()
root.mainloop()
Just add global to the img definition and it will work
The problem is Python automatically deletes the references to the variable by a process known as Garbage Collection. The solution is to save the reference or to create a new reference.
The following are the ways:
Using self to increase the reference count and to save the reference.
import tkinter
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
self.photo = tkinter.PhotoImage(file = './test.gif') # Changes here
canvas.create_image(0, 0, image=self.photo) # Changes here
root = tkinter.Tk()
test = Test(root)
root.mainloop()
Saving it to a list to increase the reference count and to save the reference.
import tkinter
l=[]
class Test:
def __init__(self, master):
canvas = tkinter.Canvas(master)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
l.append(photo)
canvas.create_image(0, 0, image=photo)
root = tkinter.Tk()
test = Test(root)
root.mainloop()
While using method 2, you can either make a global list as i did or use list inside the class. Both would work.
Some useful links:
About Garbage Collection 1
About Garbage Collection 2 (More useful)
As a rule of thumb, whenever you create your image in an indented block of code you need to safe a reference to that image. This is because of the python's automated garbage collection and it collects everything with a refcount of 0 when it destroys/leaves that frame/page/indented block of code.
The canonical way to deal with it is to have a list of images somewhere in the global namespace and add your image-references to that list. This is convenient but not very efficient and should be used for small applications.
import tkinter as tk
global_image_list = []
global_image_list.append(tk.PhotoImage(file = 'test.png'))
An more efficient way is to bound an attribute to your widget or class that holds that reference for you, as Bryan proposed in his answer. It doesn't make a difference if you do self.image or widget.image that was assigned widget = tk.Widget(.. before. But this also might not the right approach if you want to use that image further even when the widget is destroyed and garbage collected.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text='test')
label.image = tk.PhotoImage(file = 'test.png')
label.configure(image=label.image)
Just add global photo as the first line inside the function.

RMarkdown reformatting base r plot

I'm building an r package and trying to include a plot in my package vignette. Here is the code in my vignette (with options echo=F,warnings=F):
summary_table = data.frame(n_row = rep(seq(100,1000,100),each = 2),mean = c(0.087,0.137,0.278,1.880,0.859,8.742,1.782,28.908,3.928,63.544,6.648,141.373,11.158,252.689,18.409,427.515,28.220,725.520,39.675,1024.007),sd = c(0.021,0.010,0.018,0.170,0.100,0.630,0.161,1.849,0.245,3.927,0.455,12.202,0.806,14.315,1.350,37.318,2.675,63.963,2.983,102.328),package = rep(c("TDAInference","TDA"),10))
# plot table
plot(summary_table$n_row[summary_table$package=="TDA"], summary_table$mean[summary_table$package=="TDA"], type="b",
xlim=range(summary_table$n_row), ylim=range(0,summary_table$mean+1.96*summary_table$sd),xlab = "Points in diagram",ylab = "Mean execution time (sec)",main = "Benchmarking diagram_distance function")
lines(summary_table$n_row[summary_table$package=="TDAInference"], summary_table$mean[summary_table$package=="TDAInference"], col=2, type="b")
legend(x = 200,y = 800,legend = c("TDAInference","TDA"),col = c("red","black"),lty = c(1,1),cex = 0.8)
arrows(summary_table$n_row, summary_table$mean-1.96*summary_table$sd/sqrt(10), summary_table$n_row, summary_table$mean+1.96*summary_table$sd/sqrt(10), length=0.05, angle=90, code=3)
When I run the code chunk in my script it looks like this, Desired plot, which is what I want. However, when I use devtools::build_vignettes() and view the vignette it looks like this: Reformatted plot
Any idea why this is happening and how I could fix the problem?

Reverse image search implementation

I am currently trying to make a site which will contain several images with patterns and shapes (Lets say few squares and circles of various colors and shape in each picture). And I am aiming to provide the user a way to upload their images of the pattern and do a reverse image search to check whether similar pattern image already exists in my site or not. So is there any way to implement the same, either by custom code or by using any third party api/widgets etc?
Hi Ashish below is a matlab code for a function which generates signature of a particular binary object's surface, which is nearly size dependent, you can use this concept for matching a shape on different scale.
function sig = signature(bw,prec)
boundry = bwboundaries(bw);
xy = boundry{1};
x = xy(:,1);
y = xy(:,2);
len = length(x);
res = (len/prec);
re = rem(res,2);
if re
res = ceil(res);
end
indexes = 1:res:len;
xnew = x(indexes);
ynew = y(indexes);
cx = round(mean(xnew));
cy = round(mean(ynew));
xn = abs(xnew-cx);
yn = abs(ynew-cy);
sig = (xn.^2+yn.^2);
sig = sig/max(sig);
Following is the example of how to use signature function:
clc
clear all
close all
path = 'E:\GoogleDrive\Mathworks\irisDEt\shapes';
im1 = imread([path,'\3.png']);
gray1 = ((im1));
scales = [1,2,3,4];
gray1 = im2bw(gray1);
for i = 1:length(scales)
im = imresize(gray1,scales(i));
sig = signature(im,25);
figure,plot(sig)
fra = getframe();
image = frame2im(fra);
imwrite(image,['E:\GoogleDrive\Mathworks\irisDEt\shapes\',num2str(i),'.png'])
end
following is the test image and its signature for changing in size od images which looks similar in shape.
All above signatures are generated by the code given above.

Refresh image in Tkinter window

I am building an application to continuously display an image fetched from an IP camera. I have figured out how to fetch the image, and how to also display the image using Tkinter. But I cannot get it to continuously refresh the image. Using Python 2.7+.
Here is the code I have so far.
import urllib2, base64
from PIL import Image,ImageTk
import StringIO
import Tkinter
URL = 'http://myurl.cgi'
USERNAME = 'myusername'
PASSWORD = 'mypassword'
def fetch_image(url,username,password):
# this code works fine
request = urllib2.Request(url)
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
result = urllib2.urlopen(request)
imgresp = result.read()
img = Image.open(StringIO.StringIO(imgresp))
return img
root = Tkinter.Tk()
img = fetch_image(URL,USERNAME,PASSWORD)
tkimg = ImageTk.PhotoImage(img)
Tkinter.Label(root,image=tkimg).pack()
root.mainloop()
How should I edit the code so that the fetch_image is called repeatedly and its output updated in the Tkinter window?
Note that I am not using any button-events to trigger the image refresh, rather it should be refreshed automatically, say, every 1 second.
Here is a solution that uses Tkinter's Tk.after function, which schedules future calls to functions. If you replace everything after your fetch_image definition with the snipped below, you'll get the behavior you described:
root = Tkinter.Tk()
label = Tkinter.Label(root)
label.pack()
img = None
tkimg = [None] # This, or something like it, is necessary because if you do not keep a reference to PhotoImage instances, they get garbage collected.
delay = 500 # in milliseconds
def loopCapture():
print "capturing"
# img = fetch_image(URL,USERNAME,PASSWORD)
img = Image.new('1', (100, 100), 0)
tkimg[0] = ImageTk.PhotoImage(img)
label.config(image=tkimg[0])
root.update_idletasks()
root.after(delay, loopCapture)
loopCapture()
root.mainloop()

How to choose which figure on which to display an image with matplotlib

I have a python script with multiple figures that I would like to update during a loop. Some will be images, and others will be line/scatter plots. I am having trouble getting the image to display on the correct figure. (the line and scatter data are showing up on the right figures, but the image seems to always be going on the figure that was created last, eventually I'll be displaying more than one image figure, so I can't just create the image figure last)
Here is roughly the code I have so far, the 3D scatter plot is showing up on Figure 1, but both the image and the line plots are showing up on Figure 3, with Figure 2 blank:
import matplotlib.pyplot as plt
from collections import deque
class Bla():
def __init__( self ):
self.pc_fig = plt.figure(1)
self.pc_ax = self.pc_fig.add_subplot(111, projection='3d')
self.pc_ax.set_xlim3d([0, 50])
self.pc_ax.set_ylim3d([0, 50])
self.pc_ax.set_zlim3d([0, 20])
self.pc_ax.hold(False)
self.vts_fig = plt.figure(2)
self.vts_ax = self.vts_fig.add_subplot(111)
self.em_fig = plt.figure(3)
self.em_ax = self.em_fig.add_subplot(111)
self.em_ax.hold(True)
self.image_data = deque()
self.motion_data = deque()
plt.ion()
plt.show()
def run( self ):
em_prev_xy = ( 0, 0 )
while True:
if len( self.motion_data ) > 0:
data1 = self.motion_data.popleft()
em_xy = data1.get_em()
self.em_ax.plot( [ em_prev_xy[0], em_xy[0] ], [ em_prev_xy[1], em_xy[1] ],'b')
pc = self.get_pc()
pc_index = nonzero(pc>.002)
pc_value = pc[pc_index] * 100
self.pc_ax.scatter(pc_index[0],pc_index[1],pc_index[2],s=pc_value)
self.pc_ax.set_xlim3d([0, 50])
self.pc_ax.set_ylim3d([0, 50])
self.pc_ax.set_zlim3d([0, 20])
plt.pause( 0.0001 ) # This is needed for the display to update
if len( self.image_data ) > 0:
im = self.image_data.popleft()
plt.imshow( im, cmap=plt.cm.gray, axes=self.vts_ax )
plt.pause( 0.0001 )
def main():
bla = Bla()
bla.run()
if __name__ == "__main__":
main()
Basically I have some queues that get populated in a callback when new data arrives, and I want this data to be displayed as it arrives.
I am new to matplotlib, so any help with my image display issue or tips for better ways of using matplotlib to display figures in general will be much appreciated
You are mixing the OO and state machine interfaces. See this answer for an explanation of what is going on.
Replace this line:
plt.imshow( im, cmap=plt.cm.gray, axes=self.vts_ax )
with
the_axes_you_want.imshow(...)
which should fix your image issue.

Resources