- moved all plugin-related classes to Eithne.Plugin namespace
[FaRetSys.git] / Plugins / L0Mod / L0Mod.cs
blob2f0d522bd1976d05e76c757be7bd7e3f659f4e86
1 using System;
2 using System.Collections;
3 using System.Threading;
4 using System.Xml;
5 using Mono.Unix;
7 namespace Eithne
9 public class L0ModInfo : IInfo
11 public override string Name
13 get { return Catalog.GetString("Modified L<sub>0</sub> metric"); }
16 public override string ShortName
18 get { return "L0mod"; }
21 public override string Author
23 get { return "Bartosz Taudul"; }
26 public override string Description
28 get { return Catalog.GetString("This plugin calculates modified L<sub>0</sub> metric between images."); }
32 public class L0ModFactory : IFactory
34 IInfo _info = new L0ModInfo();
35 public IInfo Info
37 get { return _info; }
40 public IType Type
42 get { return IType.Comparator; }
45 public void Initialize()
49 public Plugin.Base Create()
51 return new L0ModPlugin();
55 public class TaskInfo
57 private IResult[] a_out;
58 private IImage[] a_in1;
59 private IImage[] a_in2;
60 private int start;
61 private int end;
62 private int delta;
63 private int progress = 0;
65 public TaskInfo(IResult[] a_out, IImage[] a_in1, IImage[] a_in2, int delta, int start, int end)
67 this.a_out = a_out;
68 this.a_in1 = a_in1;
69 this.a_in2 = a_in2;
70 this.start = start;
71 this.end = end;
72 this.delta = delta;
75 public void TaskWork()
77 for(int i=start; i<end; i++)
79 double[] data = new double[a_in1.Length];
81 for(int j=0; j<a_in1.Length; j++)
83 data[j] = Compare(a_in1[j], a_in2[i]);
84 progress++;
87 a_out[i] = new IResult(data);
91 private double Compare(IImage img1, IImage img2)
93 if(img1.BPP != img2.BPP)
94 throw new PluginException(Catalog.GetString("Images BPP do not match."));
95 if(img1.H != img2.H || img1.W != img2.W)
96 throw new PluginException(Catalog.GetString("Images dimensions do not match."));
98 double sum = 0;
100 if(img1.BPP == BPP.Grayscale)
101 for(int i=0; i<img1.Data.Length; i++)
103 int diff = Math.Abs(img1.Data[i] - img2.Data[i]);
104 if(diff > delta)
105 sum++;
107 else
108 for(int y=0; y<img1.H; y++)
109 for(int x=0; x<img1.W; x++)
111 float diff = Math.Abs((float)img1[x, y] - (float)img2[x, y]);
112 if(diff > delta)
113 sum++;
116 return sum / (img1.W * img1.H);
119 public int Progress
121 get { return progress; }
125 public class L0ModPlugin : Plugin.Comparator
127 private int delta = 20;
128 private ArrayList tasks = new ArrayList();
129 private int totalImages;
131 public L0ModPlugin()
133 _info = new L0ModInfo();
136 public override XmlNode Config
138 get { return GetConfig(); }
139 set { LoadConfig(value); }
142 private void UpdateValue(int n)
144 delta = n;
145 _block.Invalidate();
148 public override void Setup()
150 new L0ModSetup(delta, UpdateValue);
153 public override void Work()
155 tasks.Clear();
157 bool MultiThreading = Eithne.Config.Get("engine/blockthreads", false);
159 ICommImage socket1 = _in[0] as ICommImage;
160 ICommImage socket2 = _in[1] as ICommImage;
162 IImage[] img1 = socket1.Images;
163 IImage[] img2 = socket2.Images;
165 _out = new CommSocket(1);
167 IResult[] res = new IResult[img2.Length];
169 totalImages = img1.Length * img2.Length;
171 if(MultiThreading)
173 TaskInfo ti1 = new TaskInfo(res, img1, img2, delta, 0, img2.Length/2);
174 TaskInfo ti2 = new TaskInfo(res, img1, img2, delta, img2.Length/2, img2.Length);
176 tasks.Add(ti1);
177 tasks.Add(ti2);
179 Thread t1 = new Thread(ti1.TaskWork);
180 Thread t2 = new Thread(ti2.TaskWork);
182 t1.Start();
183 t2.Start();
185 t1.Join();
186 t2.Join();
188 else
190 TaskInfo t = new TaskInfo(res, img1, img2, delta, 0, img2.Length);
191 tasks.Add(t);
192 t.TaskWork();
195 _out[0] = new ICommResult(res, 0, socket1.OriginalImages, socket2.OriginalImages,
196 socket1.Categories, socket2.Categories);
198 tasks.Clear();
200 _workdone = true;
203 private XmlNode GetConfig()
205 XmlNode root = _xmldoc.CreateNode(XmlNodeType.Element, "config", "");
207 root.InnerText = delta.ToString();
209 return root;
212 private void LoadConfig(XmlNode root)
214 UpdateValue(Int32.Parse(root.InnerText));
217 public override int NumIn { get { return 2; } }
218 public override int NumOut { get { return 1; } }
220 public override string DescIn(int n)
222 if(n == 0)
223 return Catalog.GetString("Base images.");
224 else
225 return Catalog.GetString("Test images.");
228 public override string DescOut(int n)
230 return Catalog.GetString("Calculated modified L0 metric.");
233 private static string[] matchin = new string[] { "image/grayscale", "image/float" };
234 private static string[] matchout = new string[] { "result" };
236 public override string[] MatchIn { get { return matchin; } }
237 public override string[] MatchOut { get { return matchout; } }
239 public override float Progress
243 int done = 0;
245 if(tasks.Count == 0)
246 return 1;
248 for(int i=0; i<tasks.Count; i++)
250 done += ((TaskInfo)tasks[i]).Progress;
253 return (float)done/totalImages;