diff --git a/Fazeli_Shahroudi-Sepehr-Mastersthesis.bbl b/Fazeli_Shahroudi-Sepehr-Mastersthesis.bbl new file mode 100644 index 0000000000000000000000000000000000000000..65456746d19ed3be1137a159132ea399f31520f0 --- /dev/null +++ b/Fazeli_Shahroudi-Sepehr-Mastersthesis.bbl @@ -0,0 +1,31 @@ +% Generated by IEEEtran.bst, version: 1.14 (2015/08/26) +\begin{thebibliography}{1} +\providecommand{\url}[1]{#1} +\csname url@samestyle\endcsname +\providecommand{\newblock}{\relax} +\providecommand{\bibinfo}[2]{#2} +\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax} +\providecommand{\BIBentryALTinterwordstretchfactor}{4} +\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus +\BIBentryALTinterwordstretchfactor\fontdimen3\font minus + \fontdimen4\font\relax} +\providecommand{\BIBforeignlanguage}[2]{{% +\expandafter\ifx\csname l@#1\endcsname\relax +\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}% +\typeout{** loaded for the language `#1'. Using the pattern for}% +\typeout{** the default language instead.}% +\else +\language=\csname l@#1\endcsname +\fi +#2}} +\providecommand{\BIBdecl}{\relax} +\BIBdecl + +\bibitem{ferreira_generic_2024} +D.~Ferreira, F.~Moutinho, J.~P. Matos-Carvalho, M.~Guedes, and P.~Deusdado, + ``\BIBforeignlanguage{eng}{Generic {FPGA} {Pre}-{Processing} {Image} + {Library} for {Industrial} {Vision} {Systems}},'' + \emph{\BIBforeignlanguage{eng}{Sensors (Basel, Switzerland)}}, vol.~24, + no.~18, p. 6101, Sep. 2024. + +\end{thebibliography} diff --git a/Fazeli_Shahroudi-Sepehr-Mastersthesis.tex b/Fazeli_Shahroudi-Sepehr-Mastersthesis.tex index d943d75ba113592c22cb33dba92c01e0f5564aff..1d9886a407acd57fefa85df248946862d355dd22 100644 --- a/Fazeli_Shahroudi-Sepehr-Mastersthesis.tex +++ b/Fazeli_Shahroudi-Sepehr-Mastersthesis.tex @@ -10,11 +10,11 @@ % \usepackage{fancyhdr} \usepackage{scrlayer-scrpage} \usepackage{listings} -% \usepackage{xcolor} +\usepackage{xcolor} \usepackage{scrhack} \usepackage{longtable} \usepackage{tabularx} -\usepackage[table]{xcolor} +% \usepackage[table]{xcolor} \usepackage{array} \usepackage[T1]{fontenc} \usepackage{textcomp} @@ -38,6 +38,68 @@ % \let\oldsubsection\subsection % \renewcommand{\subsection}{\clearpage\oldsubsection} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\lstloadlanguages{C,C++,csh,Java} + +\definecolor{red}{rgb}{0.6,0,0} +\definecolor{blue}{rgb}{0,0,0.6} +\definecolor{green}{rgb}{0,0.8,0} +\definecolor{cyan}{rgb}{0.0,0.6,0.6} +\definecolor{cloudwhite}{rgb}{0.9412, 0.9608, 0.8471} + +\lstset{ +language=csh, +basicstyle=\footnotesize\ttfamily, +numbers=left, +numberstyle=\tiny, +numbersep=5pt, +tabsize=2, +extendedchars=true, +breaklines=true, +frame=b, +stringstyle=\color{blue}\ttfamily, +showspaces=false, +showtabs=false, +xleftmargin=17pt, +framexleftmargin=17pt, +framexrightmargin=5pt, +framexbottommargin=4pt, +commentstyle=\color{green}, +morecomment=[l]{//}, %use comment-line-style! +morecomment=[s]{/*}{*/}, %for multiline comments +showstringspaces=false, +morekeywords={ abstract, event, new, struct, +as, explicit, null, switch, +base, extern, object, this, +bool, false, operator, throw, +break, finally, out, true, +byte, fixed, override, try, +case, float, params, typeof, +catch, for, private, uint, +char, foreach, protected, ulong, +checked, goto, public, unchecked, +class, if, readonly, unsafe, +const, implicit, ref, ushort, +continue, in, return, using, +decimal, int, sbyte, virtual, +default, interface, sealed, volatile, +delegate, internal, short, void, +do, is, sizeof, while, +double, lock, stackalloc, +else, long, static, +enum, namespace, string}, +keywordstyle=\color{cyan}, +identifierstyle=\color{red}, +backgroundcolor=\color{cloudwhite}, +} + +\usepackage{caption} +\DeclareCaptionFont{white}{\color{white}} +\DeclareCaptionFormat{listing}{\colorbox{blue}{\parbox{\textwidth}{\hspace{5pt}#1#2#3}}} +\DeclareCaptionFormat{listingbullet}{\hspace{27.5pt}\colorbox{blue}{\parbox{0.931\textwidth}{\hspace{5pt}#1#2#3}}} +\captionsetup[lstlisting]{format=listing,labelfont=white,textfont=white, + singlelinecheck=false, margin=0pt, font={bf,footnotesize}} +\renewcommand\lstlistingname{Code} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \clearpairofpagestyles \ihead{\headmark} \ofoot*{\pagemark} @@ -98,5 +160,5 @@ \input{chapters/Appendices.tex} \bibliographystyle{IEEEtran} -\bibliography{references} +\bibliography{./sources/references.bib} \end{document} \ No newline at end of file diff --git a/IEEEtran.bst b/IEEEtran.bst new file mode 100644 index 0000000000000000000000000000000000000000..f9c03d79f4fb8df4cd260e69258dbba3bb4dfd04 --- /dev/null +++ b/IEEEtran.bst @@ -0,0 +1,2409 @@ +%% +%% IEEEtran.bst +%% BibTeX Bibliography Style file for IEEE Journals and Conferences (unsorted) +%% Version 1.14 (2015/08/26) +%% +%% Copyright (c) 2003-2015 Michael Shell +%% +%% Original starting code base and algorithms obtained from the output of +%% Patrick W. Daly's makebst package as well as from prior versions of +%% IEEE BibTeX styles: +%% +%% 1. Howard Trickey and Oren Patashnik's ieeetr.bst (1985/1988) +%% 2. Silvano Balemi and Richard H. Roy's IEEEbib.bst (1993) +%% +%% Support sites: +%% http://www.michaelshell.org/tex/ieeetran/ +%% http://www.ctan.org/pkg/ieeetran +%% and/or +%% http://www.ieee.org/ +%% +%% For use with BibTeX version 0.99a or later +%% +%% This is a numerical citation style. +%% +%%************************************************************************* +%% Legal Notice: +%% This code is offered as-is without any warranty either expressed or +%% implied; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE! +%% User assumes all risk. +%% In no event shall the IEEE or any contributor to this code be liable for +%% any damages or losses, including, but not limited to, incidental, +%% consequential, or any other damages, resulting from the use or misuse +%% of any information contained here. +%% +%% All comments are the opinions of their respective authors and are not +%% necessarily endorsed by the IEEE. +%% +%% This work is distributed under the LaTeX Project Public License (LPPL) +%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used, +%% distributed and modified. A copy of the LPPL, version 1.3, is included +%% in the base LaTeX documentation of all distributions of LaTeX released +%% 2003/12/01 or later. +%% Retain all contribution notices and credits. +%% ** Modified files should be clearly indicated as such, including ** +%% ** renaming them and changing author support contact information. ** +%%************************************************************************* + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DEFAULTS FOR THE CONTROLS OF THE BST STYLE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% These are the defaults for the user adjustable controls. The values used +% here can be overridden by the user via IEEEtranBSTCTL entry type. + +% NOTE: The recommended LaTeX command to invoke a control entry type is: +% +%\makeatletter +%\def\bstctlcite{\@ifnextchar[{\@bstctlcite}{\@bstctlcite[@auxout]}} +%\def\@bstctlcite[#1]#2{\@bsphack +% \@for\@citeb:=#2\do{% +% \edef\@citeb{\expandafter\@firstofone\@citeb}% +% \if@filesw\immediate\write\csname #1\endcsname{\string\citation{\@citeb}}\fi}% +% \@esphack} +%\makeatother +% +% It is called at the start of the document, before the first \cite, like: +% \bstctlcite{IEEEexample:BSTcontrol} +% +% IEEEtran.cls V1.6 and later does provide this command. + + + +% #0 turns off the display of the number for articles. +% #1 enables +FUNCTION {default.is.use.number.for.article} { #1 } + + +% #0 turns off the display of the paper and type fields in @inproceedings. +% #1 enables +FUNCTION {default.is.use.paper} { #1 } + + +% #0 turns off the display of urls +% #1 enables +FUNCTION {default.is.use.url} { #1 } + + +% #0 turns off the forced use of "et al." +% #1 enables +FUNCTION {default.is.forced.et.al} { #0 } + + +% The maximum number of names that can be present beyond which an "et al." +% usage is forced. Be sure that num.names.shown.with.forced.et.al (below) +% is not greater than this value! +% Note: There are many instances of references in IEEE journals which have +% a very large number of authors as well as instances in which "et al." is +% used profusely. +FUNCTION {default.max.num.names.before.forced.et.al} { #10 } + + +% The number of names that will be shown with a forced "et al.". +% Must be less than or equal to max.num.names.before.forced.et.al +FUNCTION {default.num.names.shown.with.forced.et.al} { #1 } + + +% #0 turns off the alternate interword spacing for entries with URLs. +% #1 enables +FUNCTION {default.is.use.alt.interword.spacing} { #1 } + + +% If alternate interword spacing for entries with URLs is enabled, this is +% the interword spacing stretch factor that will be used. For example, the +% default "4" here means that the interword spacing in entries with URLs can +% stretch to four times normal. Does not have to be an integer. Note that +% the value specified here can be overridden by the user in their LaTeX +% code via a command such as: +% "\providecommand\BIBentryALTinterwordstretchfactor{1.5}" in addition to +% that via the IEEEtranBSTCTL entry type. +FUNCTION {default.ALTinterwordstretchfactor} { "4" } + + +% #0 turns off the "dashification" of repeated (i.e., identical to those +% of the previous entry) names. The IEEE normally does this. +% #1 enables +FUNCTION {default.is.dash.repeated.names} { #1 } + + +% The default name format control string. +FUNCTION {default.name.format.string}{ "{f.~}{vv~}{ll}{, jj}" } + + +% The default LaTeX font command for the names. +FUNCTION {default.name.latex.cmd}{ "" } + + +% The default URL prefix. +FUNCTION {default.name.url.prefix}{ "[Online]. Available:" } + + +% Other controls that cannot be accessed via IEEEtranBSTCTL entry type. + +% #0 turns off the terminal startup banner/completed message so as to +% operate more quietly. +% #1 enables +FUNCTION {is.print.banners.to.terminal} { #1 } + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% FILE VERSION AND BANNER %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION{bst.file.version} { "1.14" } +FUNCTION{bst.file.date} { "2015/08/26" } +FUNCTION{bst.file.website} { "http://www.michaelshell.org/tex/ieeetran/bibtex/" } + +FUNCTION {banner.message} +{ is.print.banners.to.terminal + { "-- IEEEtran.bst version" " " * bst.file.version * + " (" * bst.file.date * ") " * "by Michael Shell." * + top$ + "-- " bst.file.website * + top$ + "-- See the " quote$ * "IEEEtran_bst_HOWTO.pdf" * quote$ * " manual for usage information." * + top$ + } + { skip$ } + if$ +} + +FUNCTION {completed.message} +{ is.print.banners.to.terminal + { "" + top$ + "Done." + top$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING CONSTANTS %% +%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {bbl.and}{ "and" } +FUNCTION {bbl.etal}{ "et~al." } +FUNCTION {bbl.editors}{ "eds." } +FUNCTION {bbl.editor}{ "ed." } +FUNCTION {bbl.edition}{ "ed." } +FUNCTION {bbl.volume}{ "vol." } +FUNCTION {bbl.of}{ "of" } +FUNCTION {bbl.number}{ "no." } +FUNCTION {bbl.in}{ "in" } +FUNCTION {bbl.pages}{ "pp." } +FUNCTION {bbl.page}{ "p." } +FUNCTION {bbl.chapter}{ "ch." } +FUNCTION {bbl.paper}{ "paper" } +FUNCTION {bbl.part}{ "pt." } +FUNCTION {bbl.patent}{ "Patent" } +FUNCTION {bbl.patentUS}{ "U.S." } +FUNCTION {bbl.revision}{ "Rev." } +FUNCTION {bbl.series}{ "ser." } +FUNCTION {bbl.standard}{ "Std." } +FUNCTION {bbl.techrep}{ "Tech. Rep." } +FUNCTION {bbl.mthesis}{ "Master's thesis" } +FUNCTION {bbl.phdthesis}{ "Ph.D. dissertation" } +FUNCTION {bbl.st}{ "st" } +FUNCTION {bbl.nd}{ "nd" } +FUNCTION {bbl.rd}{ "rd" } +FUNCTION {bbl.th}{ "th" } + + +% This is the LaTeX spacer that is used when a larger than normal space +% is called for (such as just before the address:publisher). +FUNCTION {large.space} { "\hskip 1em plus 0.5em minus 0.4em\relax " } + +% The LaTeX code for dashes that are used to represent repeated names. +% Note: Some older IEEE journals used something like +% "\rule{0.275in}{0.5pt}\," which is fairly thick and runs right along +% the baseline. However, the IEEE now uses a thinner, above baseline, +% six dash long sequence. +FUNCTION {repeated.name.dashes} { "------" } + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% PREDEFINED STRING MACROS %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +MACRO {jan} {"Jan."} +MACRO {feb} {"Feb."} +MACRO {mar} {"Mar."} +MACRO {apr} {"Apr."} +MACRO {may} {"May"} +MACRO {jun} {"Jun."} +MACRO {jul} {"Jul."} +MACRO {aug} {"Aug."} +MACRO {sep} {"Sep."} +MACRO {oct} {"Oct."} +MACRO {nov} {"Nov."} +MACRO {dec} {"Dec."} + + + +%%%%%%%%%%%%%%%%%% +%% ENTRY FIELDS %% +%%%%%%%%%%%%%%%%%% + +ENTRY + { address + assignee + author + booktitle + chapter + day + dayfiled + edition + editor + howpublished + institution + intype + journal + key + language + month + monthfiled + nationality + note + number + organization + pages + paper + publisher + school + series + revision + title + type + url + volume + year + yearfiled + CTLuse_article_number + CTLuse_paper + CTLuse_url + CTLuse_forced_etal + CTLmax_names_forced_etal + CTLnames_show_etal + CTLuse_alt_spacing + CTLalt_stretch_factor + CTLdash_repeated_names + CTLname_format_string + CTLname_latex_cmd + CTLname_url_prefix + } + {} + { label } + + + + +%%%%%%%%%%%%%%%%%%%%%%% +%% INTEGER VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%%% + +INTEGERS { prev.status.punct this.status.punct punct.std + punct.no punct.comma punct.period + prev.status.space this.status.space space.std + space.no space.normal space.large + prev.status.quote this.status.quote quote.std + quote.no quote.close + prev.status.nline this.status.nline nline.std + nline.no nline.newblock + status.cap cap.std + cap.no cap.yes} + +INTEGERS { longest.label.width multiresult nameptr namesleft number.label numnames } + +INTEGERS { is.use.number.for.article + is.use.paper + is.use.url + is.forced.et.al + max.num.names.before.forced.et.al + num.names.shown.with.forced.et.al + is.use.alt.interword.spacing + is.dash.repeated.names} + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%% + +STRINGS { bibinfo + longest.label + oldname + s + t + ALTinterwordstretchfactor + name.format.string + name.latex.cmd + name.url.prefix} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOW LEVEL FUNCTIONS %% +%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.controls} +{ default.is.use.number.for.article 'is.use.number.for.article := + default.is.use.paper 'is.use.paper := + default.is.use.url 'is.use.url := + default.is.forced.et.al 'is.forced.et.al := + default.max.num.names.before.forced.et.al 'max.num.names.before.forced.et.al := + default.num.names.shown.with.forced.et.al 'num.names.shown.with.forced.et.al := + default.is.use.alt.interword.spacing 'is.use.alt.interword.spacing := + default.is.dash.repeated.names 'is.dash.repeated.names := + default.ALTinterwordstretchfactor 'ALTinterwordstretchfactor := + default.name.format.string 'name.format.string := + default.name.latex.cmd 'name.latex.cmd := + default.name.url.prefix 'name.url.prefix := +} + + +% This IEEEtran.bst features a very powerful and flexible mechanism for +% controlling the capitalization, punctuation, spacing, quotation, and +% newlines of the formatted entry fields. (Note: IEEEtran.bst does not need +% or use the newline/newblock feature, but it has been implemented for +% possible future use.) The output states of IEEEtran.bst consist of +% multiple independent attributes and, as such, can be thought of as being +% vectors, rather than the simple scalar values ("before.all", +% "mid.sentence", etc.) used in most other .bst files. +% +% The more flexible and complex design used here was motivated in part by +% the IEEE's rather unusual bibliography style. For example, the IEEE ends the +% previous field item with a period and large space prior to the publisher +% address; the @electronic entry types use periods as inter-item punctuation +% rather than the commas used by the other entry types; and URLs are never +% followed by periods even though they are the last item in the entry. +% Although it is possible to accommodate these features with the conventional +% output state system, the seemingly endless exceptions make for convoluted, +% unreliable and difficult to maintain code. +% +% IEEEtran.bst's output state system can be easily understood via a simple +% illustration of two most recently formatted entry fields (on the stack): +% +% CURRENT_ITEM +% "PREVIOUS_ITEM +% +% which, in this example, is to eventually appear in the bibliography as: +% +% "PREVIOUS_ITEM," CURRENT_ITEM +% +% It is the job of the output routine to take the previous item off of the +% stack (while leaving the current item at the top of the stack), apply its +% trailing punctuation (including closing quote marks) and spacing, and then +% to write the result to BibTeX's output buffer: +% +% "PREVIOUS_ITEM," +% +% Punctuation (and spacing) between items is often determined by both of the +% items rather than just the first one. The presence of quotation marks +% further complicates the situation because, in standard English, trailing +% punctuation marks are supposed to be contained within the quotes. +% +% IEEEtran.bst maintains two output state (aka "status") vectors which +% correspond to the previous and current (aka "this") items. Each vector +% consists of several independent attributes which track punctuation, +% spacing, quotation, and newlines. Capitalization status is handled by a +% separate scalar because the format routines, not the output routine, +% handle capitalization and, therefore, there is no need to maintain the +% capitalization attribute for both the "previous" and "this" items. +% +% When a format routine adds a new item, it copies the current output status +% vector to the previous output status vector and (usually) resets the +% current (this) output status vector to a "standard status" vector. Using a +% "standard status" vector in this way allows us to redefine what we mean by +% "standard status" at the start of each entry handler and reuse the same +% format routines under the various inter-item separation schemes. For +% example, the standard status vector for the @book entry type may use +% commas for item separators, while the @electronic type may use periods, +% yet both entry handlers exploit many of the exact same format routines. +% +% Because format routines have write access to the output status vector of +% the previous item, they can override the punctuation choices of the +% previous format routine! Therefore, it becomes trivial to implement rules +% such as "Always use a period and a large space before the publisher." By +% pushing the generation of the closing quote mark to the output routine, we +% avoid all the problems caused by having to close a quote before having all +% the information required to determine what the punctuation should be. +% +% The IEEEtran.bst output state system can easily be expanded if needed. +% For instance, it is easy to add a "space.tie" attribute value if the +% bibliography rules mandate that two items have to be joined with an +% unbreakable space. + +FUNCTION {initialize.status.constants} +{ #0 'punct.no := + #1 'punct.comma := + #2 'punct.period := + #0 'space.no := + #1 'space.normal := + #2 'space.large := + #0 'quote.no := + #1 'quote.close := + #0 'cap.no := + #1 'cap.yes := + #0 'nline.no := + #1 'nline.newblock := +} + +FUNCTION {std.status.using.comma} +{ punct.comma 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.no 'cap.std := +} + +FUNCTION {std.status.using.period} +{ punct.period 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.yes 'cap.std := +} + +FUNCTION {initialize.prev.this.status} +{ punct.no 'prev.status.punct := + space.no 'prev.status.space := + quote.no 'prev.status.quote := + nline.no 'prev.status.nline := + punct.no 'this.status.punct := + space.no 'this.status.space := + quote.no 'this.status.quote := + nline.no 'this.status.nline := + cap.yes 'status.cap := +} + +FUNCTION {this.status.std} +{ punct.std 'this.status.punct := + space.std 'this.status.space := + quote.std 'this.status.quote := + nline.std 'this.status.nline := +} + +FUNCTION {cap.status.std}{ cap.std 'status.cap := } + +FUNCTION {this.to.prev.status} +{ this.status.punct 'prev.status.punct := + this.status.space 'prev.status.space := + this.status.quote 'prev.status.quote := + this.status.nline 'prev.status.nline := +} + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ { skip$ } + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + { skip$ } + if$ +} + + +% convert the strings "yes" or "no" to #1 or #0 respectively +FUNCTION {yes.no.to.int} +{ "l" change.case$ duplicate$ + "yes" = + { pop$ #1 } + { duplicate$ "no" = + { pop$ #0 } + { "unknown boolean " quote$ * swap$ * quote$ * + " in " * cite$ * warning$ + #0 + } + if$ + } + if$ +} + + +% pushes true if the single char string on the stack is in the +% range of "0" to "9" +FUNCTION {is.num} +{ chr.to.int$ + duplicate$ "0" chr.to.int$ < not + swap$ "9" chr.to.int$ > not and +} + +% multiplies the integer on the stack by a factor of 10 +FUNCTION {bump.int.mag} +{ #0 'multiresult := + { duplicate$ #0 > } + { #1 - + multiresult #10 + + 'multiresult := + } + while$ +pop$ +multiresult +} + +% converts a single character string on the stack to an integer +FUNCTION {char.to.integer} +{ duplicate$ + is.num + { chr.to.int$ "0" chr.to.int$ - } + {"noninteger character " quote$ * swap$ * quote$ * + " in integer field of " * cite$ * warning$ + #0 + } + if$ +} + +% converts a string on the stack to an integer +FUNCTION {string.to.integer} +{ duplicate$ text.length$ 'namesleft := + #1 'nameptr := + #0 'numnames := + { nameptr namesleft > not } + { duplicate$ nameptr #1 substring$ + char.to.integer numnames bump.int.mag + + 'numnames := + nameptr #1 + + 'nameptr := + } + while$ +pop$ +numnames +} + + + + +% The output routines write out the *next* to the top (previous) item on the +% stack, adding punctuation and such as needed. Since IEEEtran.bst maintains +% the output status for the top two items on the stack, these output +% routines have to consider the previous output status (which corresponds to +% the item that is being output). Full independent control of punctuation, +% closing quote marks, spacing, and newblock is provided. +% +% "output.nonnull" does not check for the presence of a previous empty +% item. +% +% "output" does check for the presence of a previous empty item and will +% remove an empty item rather than outputing it. +% +% "output.warn" is like "output", but will issue a warning if it detects +% an empty item. + +FUNCTION {output.nonnull} +{ swap$ + prev.status.punct punct.comma = + { "," * } + { skip$ } + if$ + prev.status.punct punct.period = + { add.period$ } + { skip$ } + if$ + prev.status.quote quote.close = + { "''" * } + { skip$ } + if$ + prev.status.space space.normal = + { " " * } + { skip$ } + if$ + prev.status.space space.large = + { large.space * } + { skip$ } + if$ + write$ + prev.status.nline nline.newblock = + { newline$ "\newblock " write$ } + { skip$ } + if$ +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.warn} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +% "fin.entry" is the output routine that handles the last item of the entry +% (which will be on the top of the stack when "fin.entry" is called). + +FUNCTION {fin.entry} +{ this.status.punct punct.no = + { skip$ } + { add.period$ } + if$ + this.status.quote quote.close = + { "''" * } + { skip$ } + if$ +write$ +newline$ +} + + +FUNCTION {is.last.char.not.punct} +{ duplicate$ + "}" * add.period$ + #-1 #1 substring$ "." = +} + +FUNCTION {is.multiple.pages} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {capitalize}{ "u" change.case$ "t" change.case$ } + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +FUNCTION {do.name.latex.cmd} +{ name.latex.cmd + empty$ + { skip$ } + { name.latex.cmd "{" * swap$ * "}" * } + if$ +} + +% IEEEtran.bst uses its own \BIBforeignlanguage command which directly +% invokes the TeX hyphenation patterns without the need of the Babel +% package. Babel does a lot more than switch hyphenation patterns and +% its loading can cause unintended effects in many class files (such as +% IEEEtran.cls). +FUNCTION {select.language} +{ duplicate$ empty$ 'pop$ + { language empty$ 'skip$ + { "\BIBforeignlanguage{" language * "}{" * swap$ * "}" * } + if$ + } + if$ +} + +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {space.word}{ " " swap$ * " " * } + + +% Field Conditioners, Converters, Checkers and External Interfaces + +FUNCTION {empty.field.to.null.string} +{ duplicate$ empty$ + { pop$ "" } + { skip$ } + if$ +} + +FUNCTION {either.or.check} +{ empty$ + { pop$ } + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {empty.entry.warn} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ url empty$ + and and and and and and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + + +% The bibinfo system provides a way for the electronic parsing/acquisition +% of a bibliography's contents as is done by ReVTeX. For example, a field +% could be entered into the bibliography as: +% \bibinfo{volume}{2} +% Only the "2" would show up in the document, but the LaTeX \bibinfo command +% could do additional things with the information. IEEEtran.bst does provide +% a \bibinfo command via "\providecommand{\bibinfo}[2]{#2}". However, it is +% currently not used as the bogus bibinfo functions defined here output the +% entry values directly without the \bibinfo wrapper. The bibinfo functions +% themselves (and the calls to them) are retained for possible future use. +% +% bibinfo.check avoids acting on missing fields while bibinfo.warn will +% issue a warning message if a missing field is detected. Prior to calling +% the bibinfo functions, the user should push the field value and then its +% name string, in that order. + +FUNCTION {bibinfo.check} +{ swap$ duplicate$ missing$ + { pop$ pop$ "" } + { duplicate$ empty$ + { swap$ pop$ } + { swap$ pop$ } + if$ + } + if$ +} + +FUNCTION {bibinfo.warn} +{ swap$ duplicate$ missing$ + { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } + { duplicate$ empty$ + { swap$ "empty " swap$ * " in " * cite$ * warning$ } + { swap$ pop$ } + if$ + } + if$ +} + + +% The IEEE separates large numbers with more than 4 digits into groups of +% three. The IEEE uses a small space to separate these number groups. +% Typical applications include patent and page numbers. + +% number of consecutive digits required to trigger the group separation. +FUNCTION {large.number.trigger}{ #5 } + +% For numbers longer than the trigger, this is the blocksize of the groups. +% The blocksize must be less than the trigger threshold, and 2 * blocksize +% must be greater than the trigger threshold (can't do more than one +% separation on the initial trigger). +FUNCTION {large.number.blocksize}{ #3 } + +% What is actually inserted between the number groups. +FUNCTION {large.number.separator}{ "\," } + +% So as to save on integer variables by reusing existing ones, numnames +% holds the current number of consecutive digits read and nameptr holds +% the number that will trigger an inserted space. +FUNCTION {large.number.separate} +{ 't := + "" + #0 'numnames := + large.number.trigger 'nameptr := + { t empty$ not } + { t #-1 #1 substring$ is.num + { numnames #1 + 'numnames := } + { #0 'numnames := + large.number.trigger 'nameptr := + } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames nameptr = + { duplicate$ #1 nameptr large.number.blocksize - substring$ swap$ + nameptr large.number.blocksize - #1 + global.max$ substring$ + large.number.separator swap$ * * + nameptr large.number.blocksize - 'numnames := + large.number.blocksize #1 + 'nameptr := + } + { skip$ } + if$ + } + while$ +} + +% Converts all single dashes "-" to double dashes "--". +FUNCTION {n.dashify} +{ large.number.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + + +% This function detects entries with names that are identical to that of +% the previous entry and replaces the repeated names with dashes (if the +% "is.dash.repeated.names" user control is nonzero). +FUNCTION {name.or.dash} +{ 's := + oldname empty$ + { s 'oldname := s } + { s oldname = + { is.dash.repeated.names + { repeated.name.dashes } + { s 'oldname := s } + if$ + } + { s 'oldname := s } + if$ + } + if$ +} + +% Converts the number string on the top of the stack to +% "numerical ordinal form" (e.g., "7" to "7th"). There is +% no artificial limit to the upper bound of the numbers as the +% two least significant digits determine the ordinal form. +FUNCTION {num.to.ordinal} +{ duplicate$ #-2 #1 substring$ "1" = + { bbl.th * } + { duplicate$ #-1 #1 substring$ "1" = + { bbl.st * } + { duplicate$ #-1 #1 substring$ "2" = + { bbl.nd * } + { duplicate$ #-1 #1 substring$ "3" = + { bbl.rd * } + { bbl.th * } + if$ + } + if$ + } + if$ + } + if$ +} + +% If the string on the top of the stack begins with a number, +% (e.g., 11th) then replace the string with the leading number +% it contains. Otherwise retain the string as-is. s holds the +% extracted number, t holds the part of the string that remains +% to be scanned. +FUNCTION {extract.num} +{ duplicate$ 't := + "" 's := + { t empty$ not } + { t #1 #1 substring$ + t #2 global.max$ substring$ 't := + duplicate$ is.num + { s swap$ * 's := } + { pop$ "" 't := } + if$ + } + while$ + s empty$ + 'skip$ + { pop$ s } + if$ +} + +% Converts the word number string on the top of the stack to +% Arabic string form. Will be successful up to "tenth". +FUNCTION {word.to.num} +{ duplicate$ "l" change.case$ 's := + s "first" = + { pop$ "1" } + { skip$ } + if$ + s "second" = + { pop$ "2" } + { skip$ } + if$ + s "third" = + { pop$ "3" } + { skip$ } + if$ + s "fourth" = + { pop$ "4" } + { skip$ } + if$ + s "fifth" = + { pop$ "5" } + { skip$ } + if$ + s "sixth" = + { pop$ "6" } + { skip$ } + if$ + s "seventh" = + { pop$ "7" } + { skip$ } + if$ + s "eighth" = + { pop$ "8" } + { skip$ } + if$ + s "ninth" = + { pop$ "9" } + { skip$ } + if$ + s "tenth" = + { pop$ "10" } + { skip$ } + if$ +} + + +% Converts the string on the top of the stack to numerical +% ordinal (e.g., "11th") form. +FUNCTION {convert.edition} +{ duplicate$ empty$ 'skip$ + { duplicate$ #1 #1 substring$ is.num + { extract.num + num.to.ordinal + } + { word.to.num + duplicate$ #1 #1 substring$ is.num + { num.to.ordinal } + { "edition ordinal word " quote$ * edition * quote$ * + " may be too high (or improper) for conversion" * " in " * cite$ * warning$ + } + if$ + } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LATEX BIBLIOGRAPHY CODE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {start.entry} +{ newline$ + "\bibitem{" write$ + cite$ write$ + "}" write$ + newline$ + "" + initialize.prev.this.status +} + +% Here we write out all the LaTeX code that we will need. The most involved +% code sequences are those that control the alternate interword spacing and +% foreign language hyphenation patterns. The heavy use of \providecommand +% gives users a way to override the defaults. Special thanks to Javier Bezos, +% Johannes Braams, Robin Fairbairns, Heiko Oberdiek, Donald Arseneau and all +% the other gurus on comp.text.tex for their help and advice on the topic of +% \selectlanguage, Babel and BibTeX. +FUNCTION {begin.bib} +{ "% Generated by IEEEtran.bst, version: " bst.file.version * " (" * bst.file.date * ")" * + write$ newline$ + preamble$ empty$ 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * + write$ newline$ + "\providecommand{\url}[1]{#1}" + write$ newline$ + "\csname url@samestyle\endcsname" + write$ newline$ + "\providecommand{\newblock}{\relax}" + write$ newline$ + "\providecommand{\bibinfo}[2]{#2}" + write$ newline$ + "\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax}" + write$ newline$ + "\providecommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + "\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus " + write$ newline$ + "\BIBentryALTinterwordstretchfactor\fontdimen3\font minus \fontdimen4\font\relax}" + write$ newline$ + "\providecommand{\BIBforeignlanguage}[2]{{%" + write$ newline$ + "\expandafter\ifx\csname l@#1\endcsname\relax" + write$ newline$ + "\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}%" + write$ newline$ + "\typeout{** loaded for the language `#1'. Using the pattern for}%" + write$ newline$ + "\typeout{** the default language instead.}%" + write$ newline$ + "\else" + write$ newline$ + "\language=\csname l@#1\endcsname" + write$ newline$ + "\fi" + write$ newline$ + "#2}}" + write$ newline$ + "\providecommand{\BIBdecl}{\relax}" + write$ newline$ + "\BIBdecl" + write$ newline$ +} + +FUNCTION {end.bib} +{ newline$ "\end{thebibliography}" write$ newline$ } + +FUNCTION {if.url.alt.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentryALTinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + +FUNCTION {if.url.std.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentrySTDinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%% +%% LONGEST LABEL PASS %% +%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} + +FUNCTION {longest.label.pass} +{ type$ "ieeetranbstctl" = + { skip$ } + { number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + { skip$ } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%% +%% FORMAT HANDLERS %% +%%%%%%%%%%%%%%%%%%%%% + +%% Lower Level Formats (used by higher level formats) + +FUNCTION {format.address.org.or.pub.date} +{ 't := + "" + year empty$ + { "empty year in " cite$ * warning$ } + { skip$ } + if$ + address empty$ t empty$ and + year empty$ and month empty$ and + { skip$ } + { this.to.prev.status + this.status.std + cap.status.std + address "address" bibinfo.check * + t empty$ + { skip$ } + { punct.period 'prev.status.punct := + space.large 'prev.status.space := + address empty$ + { skip$ } + { ": " * } + if$ + t * + } + if$ + year empty$ month empty$ and + { skip$ } + { t empty$ address empty$ and + { skip$ } + { ", " * } + if$ + month empty$ + { year empty$ + { skip$ } + { year "year" bibinfo.check * } + if$ + } + { month "month" bibinfo.check * + year empty$ + { skip$ } + { " " * year "year" bibinfo.check * } + if$ + } + if$ + } + if$ + } + if$ +} + + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + this.to.prev.status + this.status.std + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + name.format.string + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { nameptr num.names.shown.with.forced.et.al #1 + = + numnames max.num.names.before.forced.et.al > + is.forced.et.al and and + { "others" 't := + #1 'namesleft := + } + { skip$ } + if$ + namesleft #1 > + { ", " * t do.name.latex.cmd * } + { s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { " " * bbl.etal emphasize * } + { numnames #2 > + { "," * } + { skip$ } + if$ + bbl.and + space.word * t do.name.latex.cmd * + } + if$ + } + if$ + } + { t do.name.latex.cmd } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + cap.status.std + } if$ +} + + + + +%% Higher Level Formats + +%% addresses/locations + +FUNCTION {format.address} +{ address duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% author/editor names + +FUNCTION {format.authors}{ author "author" format.names } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { ", " * + get.bbl.editor + capitalize + * + } + if$ +} + + + +%% date + +FUNCTION {format.date} +{ + month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "there's a month but no year in " cite$ * warning$ } + if$ + * + } + { this.to.prev.status + this.status.std + cap.status.std + swap$ 'skip$ + { + swap$ + " " * swap$ + } + if$ + * + } + if$ +} + +FUNCTION {format.date.electronic} +{ month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ + { pop$ } + { "there's a month but no year in " cite$ * warning$ + pop$ ")" * "(" swap$ * + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ + } + { swap$ + { swap$ pop$ ")" * "(" swap$ * } + { "(" swap$ * ", " * swap$ * ")" * } + if$ + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ +} + + + +%% edition/title + +% Note: The IEEE considers the edition to be closely associated with +% the title of a book. So, in IEEEtran.bst the edition is normally handled +% within the formatting of the title. The format.edition function is +% retained here for possible future use. +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + convert.edition + status.cap + { "t" } + { "l" } + if$ change.case$ + "edition" bibinfo.check + "~" * bbl.edition * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of a conference proceedings. +% Here we use the "intype" field to provide the user a way to +% override the word "in" (e.g., with things like "presented at") +% Use of intype stops the emphasis of the booktitle to indicate that +% we no longer mean the written conference proceedings, but the +% conference itself. +FUNCTION {format.in.booktitle} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + intype missing$ + { emphasize + bbl.in " " * + } + { intype " " * } + if$ + swap$ * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of collection. +% Here the "intype" field is not supported, but "edition" is. +FUNCTION {format.in.booktitle.edition} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + "l" change.case$ + * "~" * bbl.edition * + } + if$ + bbl.in " " * swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ 'skip$ + { quote.close 'this.status.quote := + is.last.char.not.punct + { punct.std 'this.status.punct := } + { punct.no 'this.status.punct := } + if$ + select.language + "``" swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title.electronic} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ + { skip$ } + { select.language } + if$ +} + +FUNCTION {format.book.title.edition} +{ title "title" bibinfo.check + duplicate$ empty$ + { "empty title in " cite$ * warning$ } + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + status.cap + { "t" } + { "l" } + if$ + change.case$ + * "~" * bbl.edition * + } + if$ + cap.status.std + } + if$ +} + +FUNCTION {format.book.title} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% journal + +FUNCTION {format.journal} +{ journal duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% how published + +FUNCTION {format.howpublished} +{ howpublished duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% institutions/organization/publishers/school + +FUNCTION {format.institution} +{ institution duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.organization} +{ organization duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.address.publisher.date} +{ publisher "publisher" bibinfo.warn format.address.org.or.pub.date } + +FUNCTION {format.address.publisher.date.nowarn} +{ publisher "publisher" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.address.organization.date} +{ organization "organization" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.school} +{ school duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% volume/number/series/chapter/pages + +FUNCTION {format.volume} +{ volume empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + bbl.volume + status.cap + { capitalize } + { skip$ } + if$ + swap$ tie.or.space.prefix + "volume" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number} +{ number empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + status.cap + { bbl.number capitalize } + { bbl.number } + if$ + swap$ tie.or.space.prefix + "number" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number.if.use.for.article} +{ is.use.number.for.article + { format.number } + { "" } + if$ +} + +% The IEEE does not seem to tie the series so closely with the volume +% and number as is done in other bibliography styles. Instead the +% series is treated somewhat like an extension of the title. +FUNCTION {format.series} +{ series empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.series " " * + series "series" bibinfo.check * + cap.status.std + } + if$ +} + + +FUNCTION {format.chapter} +{ chapter empty$ + { "" } + { this.to.prev.status + this.status.std + type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + cap.status.std + } + if$ +} + + +% The intended use of format.paper is for paper numbers of inproceedings. +% The paper type can be overridden via the type field. +% We allow the type to be displayed even if the paper number is absent +% for things like "postdeadline paper" +FUNCTION {format.paper} +{ is.use.paper + { paper empty$ + { type empty$ + { "" } + { this.to.prev.status + this.status.std + type "type" bibinfo.check + cap.status.std + } + if$ + } + { this.to.prev.status + this.status.std + type empty$ + { bbl.paper } + { type "type" bibinfo.check } + if$ + " " * paper + "paper" bibinfo.check + * + cap.status.std + } + if$ + } + { "" } + if$ +} + + +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + duplicate$ is.multiple.pages + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + cap.status.std + } + if$ +} + + + +%% technical report number + +FUNCTION {format.tech.report.number} +{ number "number" bibinfo.check + this.to.prev.status + this.status.std + cap.status.std + type duplicate$ empty$ + { pop$ + bbl.techrep + } + { skip$ } + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ } + { tie.or.space.prefix * * } + if$ +} + + + +%% note + +FUNCTION {format.note} +{ note empty$ + { "" } + { this.to.prev.status + this.status.std + punct.period 'this.status.punct := + note #1 #1 substring$ + duplicate$ "{" = + { skip$ } + { status.cap + { "u" } + { "l" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + cap.yes 'status.cap := + } + if$ +} + + + +%% patent + +FUNCTION {format.patent.date} +{ this.to.prev.status + this.status.std + year empty$ + { monthfiled duplicate$ empty$ + { "monthfiled" bibinfo.check pop$ "" } + { "monthfiled" bibinfo.check } + if$ + dayfiled duplicate$ empty$ + { "dayfiled" bibinfo.check pop$ "" * } + { "dayfiled" bibinfo.check + monthfiled empty$ + { "dayfiled without a monthfiled in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + yearfiled empty$ + { "no year or yearfiled in " cite$ * warning$ } + { yearfiled "yearfiled" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + } + { month duplicate$ empty$ + { "month" bibinfo.check pop$ "" } + { "month" bibinfo.check } + if$ + day duplicate$ empty$ + { "day" bibinfo.check pop$ "" * } + { "day" bibinfo.check + month empty$ + { "day without a month in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + year "year" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + cap.status.std +} + +FUNCTION {format.patent.nationality.type.number} +{ this.to.prev.status + this.status.std + nationality duplicate$ empty$ + { "nationality" bibinfo.warn pop$ "" } + { "nationality" bibinfo.check + duplicate$ "l" change.case$ "united states" = + { pop$ bbl.patentUS } + { skip$ } + if$ + " " * + } + if$ + type empty$ + { bbl.patent "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.warn pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + + + +%% standard + +FUNCTION {format.organization.institution.standard.type.number} +{ this.to.prev.status + this.status.std + organization duplicate$ empty$ + { pop$ + institution duplicate$ empty$ + { "institution" bibinfo.warn } + { "institution" bibinfo.warn " " * } + if$ + } + { "organization" bibinfo.warn " " * } + if$ + type empty$ + { bbl.standard "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.check pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + +FUNCTION {format.revision} +{ revision empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.revision + revision tie.or.space.prefix + "revision" bibinfo.check + * * + cap.status.std + } + if$ +} + + +%% thesis + +FUNCTION {format.master.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.mthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + +FUNCTION {format.phd.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.phdthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + + + +%% URL + +FUNCTION {format.url} +{ is.use.url + { url empty$ + { "" } + { this.to.prev.status + this.status.std + cap.yes 'status.cap := + name.url.prefix " " * + "\url{" * url * "}" * + punct.no 'this.status.punct := + punct.period 'prev.status.punct := + space.normal 'this.status.space := + space.normal 'prev.status.space := + quote.no 'this.status.quote := + } + if$ + } + { "" } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%% +%% ENTRY HANDLERS %% +%%%%%%%%%%%%%%%%%%%% + + +% Note: In many journals, the IEEE (or the authors) tend not to show the number +% for articles, so the display of the number is controlled here by the +% switch "is.use.number.for.article" +FUNCTION {article} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.journal "journal" bibinfo.check "journal" output.warn + format.volume output + format.number.if.use.for.article output + format.pages output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {book} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + author empty$ + { skip$ } + { format.editors output } + if$ + format.address.publisher.date output + format.volume output + format.number output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {booklet} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {electronic} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.article.title.electronic output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {inbook} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + format.address.publisher.date output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {incollection} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle.edition "booktitle" output.warn + format.series output + format.editors output + format.address.publisher.date.nowarn output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {inproceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle "booktitle" output.warn + format.series output + format.editors output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.paper output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {manual} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title.edition "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {mastersthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.master.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {misc} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.pages output + format.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {patent} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.patent.nationality.type.number output + format.patent.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {periodical} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + format.organization "organization" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {phdthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.phd.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {proceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {standard} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization.institution.standard.type.number output + format.revision output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {techreport} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.institution "institution" bibinfo.warn output + format.address "address" bibinfo.check output + format.tech.report.number output.nonnull + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {unpublished} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.date output + format.note "note" output.warn + format.url output + fin.entry + if.url.std.interword.spacing +} + + +% The special entry type which provides the user interface to the +% BST controls +FUNCTION {IEEEtranBSTCTL} +{ is.print.banners.to.terminal + { "** IEEEtran BST control entry " quote$ * cite$ * quote$ * " detected." * + top$ + } + { skip$ } + if$ + CTLuse_article_number + empty$ + { skip$ } + { CTLuse_article_number + yes.no.to.int + 'is.use.number.for.article := + } + if$ + CTLuse_paper + empty$ + { skip$ } + { CTLuse_paper + yes.no.to.int + 'is.use.paper := + } + if$ + CTLuse_url + empty$ + { skip$ } + { CTLuse_url + yes.no.to.int + 'is.use.url := + } + if$ + CTLuse_forced_etal + empty$ + { skip$ } + { CTLuse_forced_etal + yes.no.to.int + 'is.forced.et.al := + } + if$ + CTLmax_names_forced_etal + empty$ + { skip$ } + { CTLmax_names_forced_etal + string.to.integer + 'max.num.names.before.forced.et.al := + } + if$ + CTLnames_show_etal + empty$ + { skip$ } + { CTLnames_show_etal + string.to.integer + 'num.names.shown.with.forced.et.al := + } + if$ + CTLuse_alt_spacing + empty$ + { skip$ } + { CTLuse_alt_spacing + yes.no.to.int + 'is.use.alt.interword.spacing := + } + if$ + CTLalt_stretch_factor + empty$ + { skip$ } + { CTLalt_stretch_factor + 'ALTinterwordstretchfactor := + "\renewcommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + } + if$ + CTLdash_repeated_names + empty$ + { skip$ } + { CTLdash_repeated_names + yes.no.to.int + 'is.dash.repeated.names := + } + if$ + CTLname_format_string + empty$ + { skip$ } + { CTLname_format_string + 'name.format.string := + } + if$ + CTLname_latex_cmd + empty$ + { skip$ } + { CTLname_latex_cmd + 'name.latex.cmd := + } + if$ + CTLname_url_prefix + missing$ + { skip$ } + { CTLname_url_prefix + 'name.url.prefix := + } + if$ + + + num.names.shown.with.forced.et.al max.num.names.before.forced.et.al > + { "CTLnames_show_etal cannot be greater than CTLmax_names_forced_etal in " cite$ * warning$ + max.num.names.before.forced.et.al 'num.names.shown.with.forced.et.al := + } + { skip$ } + if$ +} + + +%%%%%%%%%%%%%%%%%%% +%% ENTRY ALIASES %% +%%%%%%%%%%%%%%%%%%% +FUNCTION {conference}{inproceedings} +FUNCTION {online}{electronic} +FUNCTION {internet}{electronic} +FUNCTION {webpage}{electronic} +FUNCTION {www}{electronic} +FUNCTION {default.type}{misc} + + + +%%%%%%%%%%%%%%%%%% +%% MAIN PROGRAM %% +%%%%%%%%%%%%%%%%%% + +READ + +EXECUTE {initialize.controls} +EXECUTE {initialize.status.constants} +EXECUTE {banner.message} + +EXECUTE {initialize.longest.label} +ITERATE {longest.label.pass} + +EXECUTE {begin.bib} +ITERATE {call.type$} +EXECUTE {end.bib} + +EXECUTE{completed.message} + + +%% That's all folks, mds. diff --git a/chapters/3-Implementation.tex b/chapters/3-Implementation.tex index 0a4c866095f70335a7bc9c8e6b911c6bdd2649e3..3d5cf6ec9b1453eef5a05adca43972f40148855c 100644 --- a/chapters/3-Implementation.tex +++ b/chapters/3-Implementation.tex @@ -1 +1,17 @@ -\chapter{Implementation} \ No newline at end of file +\chapter{Implementation} + +This chapter details the implementation of a comprehensive benchmarking framework to evaluate several image processing libraries, including ImageSharp, OpenCvSharp paired with SkiaSharp, Emgu CV coupled with Structure.Sketching, and Magick.NET integrated with MagicScaler. The objective was to create an endâ€toâ€end system that not only measures execution times for common image operations but also provides insights into memory usage. + +This has been sought to answer key questions regarding the efficiency of image conversion and pixel iteration operations—two fundamental tasks in image processing. The following sections describe the review process, architectural decisions, and technical implementations in the study.extensive study. + +\input{sections/Chapter-3-sections/System-Architecture.tex} + +\input{sections/Chapter-3-sections/Image-Conversion.tex} + +\input{sections/Chapter-3-sections/Pixel-Iteration.tex} + +\input{sections/Chapter-3-sections/Libraries-Implementation.tex} + +\input{sections/Chapter-3-sections/Memory-Profiling.tex} + +\input{sections/Chapter-3-sections/Result-Export.tex} \ No newline at end of file diff --git a/chapters/Appendices.tex b/chapters/Appendices.tex index fddc37a0797414b527b3360b71caccbc007270ce..02d6cd54e218b0aa17265953abba7653c23cf676 100755 --- a/chapters/Appendices.tex +++ b/chapters/Appendices.tex @@ -1,4 +1,5 @@ \chapter{Appendices} +\cite{ferreira_generic_2024} \input{chapters/Appendices/appendix_a.tex} \input{chapters/Appendices/appendix_b.tex} \input{chapters/Appendices/appendix_c.tex} \ No newline at end of file diff --git a/sections/Chapter-3-sections/Tasks.tex b/outdated/Tasks.tex similarity index 100% rename from sections/Chapter-3-sections/Tasks.tex rename to outdated/Tasks.tex diff --git a/sections/Chapter-3-sections/performance-metrics.tex b/outdated/performance-metrics.tex similarity index 100% rename from sections/Chapter-3-sections/performance-metrics.tex rename to outdated/performance-metrics.tex diff --git a/sections/Chapter-3-sections/Image-Conversion.tex b/sections/Chapter-3-sections/Image-Conversion.tex new file mode 100644 index 0000000000000000000000000000000000000000..f46035d24098e08b89ca542e5c1fa68d8fd7790f --- /dev/null +++ b/sections/Chapter-3-sections/Image-Conversion.tex @@ -0,0 +1,65 @@ +\section{Benchmarking Implementation} + +The implementation of the benchmarking framework is divided into two main tests: the image conversion benchmark and the pixel iteration benchmark. Both tests follow a similar structure, starting with a warm-up phase to mitigate initialization effects, followed by a series of iterations where performance metrics are recorded. + +\subsection{Image Conversion Benchmark Implementation} + +The image conversion benchmark is designed to measure the time it takes to load an image from disk, convert its format, and save the result. This process is critical in many image processing pipelines, where quick and efficient conversion between formats can significantly impact overall throughput. + +The code snippet below illustrates the core routine for this benchmark. The process begins with a series of warm-up iterations, during which the system’s just-in-time (JIT) compilation and caching mechanisms are activated. After the warm-up phase, the main iterations are executed, with each iteration logging the time taken for the conversion. + +\begin{lstlisting}[language={[Sharp]C}, caption={Image conversion benchmark implementation (ImageSharp-Testing.cs)}] +public class ImageConversionBenchmark +{ + public static (double warmupTime, double averageTime, double totalTime) RunBenchmark(string inputPath, string outputPath, int iterations) + { + long totalElapsedMilliseconds = 0; + long warmupTime = 0; + int warmupIterations = 5; + Stopwatch stopwatch = new Stopwatch(); + + // Warm-up iterations to allow the system to reach steady state. + for (int i = 0; i < warmupIterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + using (Image image = Image.Load(inputPath)) + { + using (FileStream fs = new FileStream(outputPath, FileMode.Create)) + { + image.Save(fs, new PngEncoder()); + } + } + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; + } + + // Main iterations where actual performance data is collected. + for (int i = 0; i < iterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + using (Image image = Image.Load(inputPath)) + { + using (FileStream fs = new FileStream(outputPath, FileMode.Create)) + { + image.Save(fs, new PngEncoder()); + } + } + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Image conversion took {stopwatch.ElapsedMilliseconds} ms"); + } + + double averageTime = totalElapsedMilliseconds / (double)iterations; + double totalTime = warmupTime + totalElapsedMilliseconds; + Console.WriteLine($"Warm-up: {warmupTime} ms, Average: {averageTime} ms, Total: {totalTime} ms"); + + return (warmupTime, averageTime, totalTime); + } +} +\end{lstlisting} + +In the code, the warm-up phase runs for five iterations. Each iteration loads the image, saves it as a PNG, and then accumulates the elapsed time. After the warm-up, the main test performs 100 iterations of the same operation, allowing us to compute an average execution time. The rationale behind this design is to isolate the steady-state performance from any one-time overhead, ensuring that the reported metrics reflect the true operational cost of image conversion. + +The story behind this implementation is one of iterative refinement. Early tests revealed that the initial iterations were significantly slower, prompting the introduction of the warm-up phase. Over time, it has been refined the benchmarking routine to ensure that every iteration is as isolated as possible, thereby reducing the influence of transient system states. \ No newline at end of file diff --git a/sections/Chapter-3-sections/Libraries-Implementation.tex b/sections/Chapter-3-sections/Libraries-Implementation.tex new file mode 100644 index 0000000000000000000000000000000000000000..2b3778687ee04e98c66b27d22a949ec7472e0e77 --- /dev/null +++ b/sections/Chapter-3-sections/Libraries-Implementation.tex @@ -0,0 +1,359 @@ +\section{Libraries Implementation} +As discussed in the Methodology chapter, a comprehensive evaluation was undertaken to assess the strengths and limitations of various image processing libraries. This analysis informed the decision to implement integrations for frameworks: OpenCvSharp with SkiaSharp, and Emgu CV with Structure.Sketching, and Magick.NET with MagicScaler. The following excerpt presents representative code segments that illustrate the implementation strategies developed for these libraries. These segments not only capture the theoretical rationale behind each implementation approach but also reflect the practical constraints and performance considerations addressed throughout the thesis. This compilation of code serves as a testament to the systematic, experimental, and iterative nature of the research, highlighting the rigorous engineering process that underpinned the development of a robust image processing benchmarking framework. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{OpenCvSharp and SkiaSharp Implementation} + +The following implementation shows how the OpenCvSharp and SkiaSharp libraries are integrated to perform image conversion and pixel iteration tasks. Image conversion was implemented using OpenCvSharp, while pixel iteration was implemented using SkiaSharp. + +\begin{lstlisting}[language={[Sharp]C}, caption={SkiaSharp Implementation (RunBenchmark Method)}, label={lst:skia_sharp_RunBenchmarkMethod}] +using OpenCvSharp; +using SkiaSharp; + +// Image Conversion logic using SkiaSharp +public class ImageConversionBenchmark +{ + public static (double warmupTime, double averageTimeExcludingWarmup, double totalTimeIncludingWarmup) RunBenchmark(string inputPath, string outputPath, int iterations) +\end{lstlisting} + +The ImageConversionBenchmark class contains a static method RunBenchmark that takes the input image path, output image path, and number of iterations as input parameters. The method returns a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up, which will be used to form the results Excel file. + +\begin{lstlisting}[language={[Sharp]C}, caption={SkiaSharp Implementation (Initialization)}, label={lst:skia_sharp_initialization}] + { + long totalElapsedMilliseconds = 0; + long warmupTime = 0; + int warmupIterations = 5; + Stopwatch stopwatch = new Stopwatch(); +\end{lstlisting} + +First, the totalElapsedMilliseconds and warmupTime variables are initialized and as discussed in the methodology chapter, the warmupIterations are set to 5. A stopwatch object is created to measure the elapsed time for each iteration. + +\begin{lstlisting}[language={[Sharp]C}, caption={SkiaSharp Implementation (Warm-up Iterations)}] + // Warm-up iterations + for (int i = 0; i < warmupIterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = Cv2.ImRead(inputPath, ImreadModes.Color)) + { + Cv2.ImWrite(outputPath, image); + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; + } +\end{lstlisting} + +The warm-up phase is executed five times to ensure that the libraries are fully initialized before the main iterations begin. In each iteration, the code reads an image using \texttt{Cv2.ImRead}, and writes the image using \texttt{Cv2.ImWrite}. The elapsed time for each iteration is recorded using the stopwatch object. + +\begin{lstlisting}[language={[Sharp]C}, caption={SkiaSharp Implementation (Main Iterations)}] + // Main iterations + for (int i = 0; i < iterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = Cv2.ImRead(inputPath, ImreadModes.Color)) + { + Cv2.ImWrite(outputPath, image); + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Image conversion took {stopwatch.ElapsedMilliseconds} ms"); + } +\end{lstlisting} + +After the warm-up phase, the main iterations are executed, and the elapsed time for each iteration is recorded. The results are then aggregated and returned as a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. + +\begin{lstlisting}[language={[Sharp]C}, caption={SkiaSharp Implementation (Results Calculation)}] + double averageTimeExcludingWarmup = totalElapsedMilliseconds / (double)iterations; + double totalTimeIncludingWarmup = warmupTime + totalElapsedMilliseconds; + + Console.WriteLine($"Warm-up time for image conversion: {warmupTime} ms"); + Console.WriteLine($"Average time excluding warm-up for image conversion: {averageTimeExcludingWarmup} ms"); + Console.WriteLine($"Total time including warm-up for image conversion: {totalTimeIncludingWarmup} ms"); + + return (warmupTime, averageTimeExcludingWarmup, totalTimeIncludingWarmup); + } +} +\end{lstlisting} + +Finally, the average time excluding warm-up, total time including warm-up, and warm-up time are calculated. These values are then printed to the console and returned as a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. + +The pixel iteration benchmark, on the other hand, uses SkiaSharp to perform pixel-wise operations on the image. + +Same as the image conversion benchmark, the pixel iteration benchmark is implemented as a static method RunBenchmark that takes the image path and the number of iterations as input parameters. The method returns a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. And in the same way variables are initialized. + +\begin{lstlisting}[language={[Sharp]C}, caption={OpenCvSharp Implementation (Warm-up Iterations)}] + // Warm-up iterations + for (int i = 0; i < warmupIterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = Cv2.ImRead(imagePath, ImreadModes.Color)) + { + for (int y = 0; y < image.Rows; y++) + { + for (int x = 0; x < image.Cols; x++) + { + var pixel = image.At<Vec3b>(y, x); + byte gray = (byte)((pixel.Item0 + pixel.Item1 + pixel.Item2) / 3); + image.Set(y, x, new Vec3b(gray, gray, gray)); + } + } + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; + } +\end{lstlisting} + +The warm-up phase is executed five times to ensure that the libraries are fully initialized before the main iterations begin. In each iteration, the code reads an image using \texttt{Cv2.ImRead}, iterates over each pixel, calculates the grayscale value, and then sets the pixel value using \texttt{image.At<Vec3b>} and \texttt{image.Set}. The elapsed time for each iteration is recorded using the stopwatch object. + +\begin{lstlisting}[language={[Sharp]C}, caption={OpenCvSharp Implementation (Main Iterations)}] + // Main iterations + for (int i = 0; i < iterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = Cv2.ImRead(imagePath, ImreadModes.Color)) + { + for (int y = 0; y < image.Rows; y++) + { + for (int x = 0; x < image.Cols; x++) + { + var pixel = image.At<Vec3b>(y, x); + byte gray = (byte)((pixel.Item0 + pixel.Item1 + pixel.Item2) / 3); + image.Set(y, x, new Vec3b(gray, gray, gray)); + } + } + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Pixel iteration took {stopwatch.ElapsedMilliseconds} ms"); + } +\end{lstlisting} + +After the warm-up phase, the main iterations are executed, using the same logic as the warm-up phase. The elapsed time for each iteration is recorded, and the results are then aggregated and returned as a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. + +\begin{lstlisting}[language={[Sharp]C}, caption={OpenCvSharp Implementation (Results Calculation)}] + double averageTimeExcludingWarmup = totalElapsedMilliseconds / (double)iterations; + double totalTimeIncludingWarmup = warmupTime + totalElapsedMilliseconds; + + Console.WriteLine($"Warm-up time for pixel iteration: {warmupTime} ms"); + Console.WriteLine($"Average time excluding warm-up for pixel iteration: {averageTimeExcludingWarmup} ms"); + Console.WriteLine($"Total time including warm-up for pixel iteration: {totalTimeIncludingWarmup} ms"); + + return (warmupTime, averageTimeExcludingWarmup, totalTimeIncludingWarmup); + } +} +\end{lstlisting}   + +Finally, the average time excluding warm-up, total time including warm-up, and warm-up time are calculated. These values are then printed to the console and returned as a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. The returned values are then used to generate the results in an Excel file. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Magick.NET Implementation} + +In the implementation of both image conversion and pixel iteration benchmarks, Magick.NET library was used. This decision was based on Magick.NET's comprehensive functionality, which includes support for high-quality image conversion and efficient pixel-wise operations. \\ + +Similar to the previous section on OpenCvSharp and SkiaSharp, the ImageConversionBenchmark class for Magick.NET features a static RunBenchmark method. In this method, the necessary variables are initialized to measure and record the performance of image conversion operations. This consistent approach across libraries facilitates a clear comparison of their performance under similar conditions.\\ + +In logic for the warm-up phase and main iterations, change was only the library-specific functions used for image conversion and pixel iteration. Implementing image conversion using Magick.NET involved reading an image using \texttt{new MagickImage(inputPath)} to read an image and \texttt{image.Write(outputPath, MagickFormat.Png)} to write an image, and the image conversion benchmark was implemented. + +\begin{lstlisting}[language={[Sharp]C}, caption={Magick.NET Implementation (Image Conversion)}, label={lst:magicknet_imageconversion}] +// Warm-up iterations +for (int i = 0; i < warmupIterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = new MagickImage(inputPath)) + { + image.Write(outputPath, MagickFormat.Png); + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; +} + +// Main iterations +for (int i = 0; i < iterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = new MagickImage(inputPath)) + { + image.Write(outputPath, MagickFormat.Png); + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Image conversion took {stopwatch.ElapsedMilliseconds} ms"); +} +\end{lstlisting} + +The pixel iteration benchmark was implemented by first retrieving the pixel data using the \texttt{image.GetPixels()} method. Then, for each pixel, the color channels were set to the same gray value using the \texttt{pixels.SetPixel(x, y, new ushort[] \{ gray, gray, gray \})} function. This process was repeated for each pixel in the image for both the warm-up phase and the main iterations. + +\begin{lstlisting}[language={[Sharp]C}, caption={Magick.NET Implementation (Pixel Iteration)}, label={lst:magicknet_pixel_iteration}] +// Warm-up iterations +for (int i = 0; i < warmupIterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = new MagickImage(imagePath)) + { + var pixels = image.GetPixels(); + for (int y = 0; y < image.Height; y++) + { + for (int x = 0; x < image.Width; x++) + { + var pixel = pixels.GetPixel(x, y); // Get pixel data + ushort gray = (ushort)((pixel[0] + pixel[1] + pixel[2]) / 3); // Convert to grayscale + pixels.SetPixel(x, y, new ushort[] { gray, gray, gray }); // Set pixel data with ushort[] + } + } + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; +} + +// Main iterations +for (int i = 0; i < iterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (var image = new MagickImage(imagePath)) + { + var pixels = image.GetPixels(); + for (int y = 0; y < image.Height; y++) + { + for (int x = 0; x < image.Width; x++) + { + var pixel = pixels.GetPixel(x, y); // Get pixel data + ushort gray = (ushort)((pixel[0] + pixel[1] + pixel[2]) / 3); // Convert to grayscale + pixels.SetPixel(x, y, new ushort[] { gray, gray, gray }); // Set pixel data with ushort[] + } + } + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Pixel iteration took {stopwatch.ElapsedMilliseconds} ms"); +} +\end{lstlisting} + +The results of the image conversion and pixel iteration benchmarks were then like the previous libraries, aggregated and returned as a tuple containing the warm-up time, average time excluding warm-up, and total time including warm-up. These values were then used to generate the results in an Excel file. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsection{Emgu CV and Structure.Sketching Implementation} + +The implementation of Emgu CV and Structure.Sketching libraries in the benchmarking framework are shown in the following code snippet. The code demonstrates how the Emgu CV library is used for image conversion, while Structure.Sketching is used for pixel iteration. + +For image conversion, the code reads an image using \texttt{CvInvoke.Imread} and writes the image using \texttt{CvInvoke.Imwrite}. The warm-up phase and main iterations are executed in a similar manner to the previous libraries, with the elapsed time for each iteration recorded using a stopwatch object. + +\begin{lstlisting}[language={[Sharp]C}, caption={Emgu CV Implementation (Image Conversion)}, label={lst:emgu_cv_structure_sketching_image_conversion}] +using Emgu.CV; +using Emgu.CV.CvEnum; +using Emgu.CV.Structure; +using Structure.Sketching; +using Structure.Sketching.Formats; +using Structure.Sketching.Colors; + +// Warm-up iterations +for (int i = 0; i < warmupIterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (Mat image = CvInvoke.Imread(inputPath, ImreadModes.Color)) + { + CvInvoke.Imwrite(outputPath, image); + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; +} + +// Main iterations +for (int i = 0; i < iterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + using (Mat image = CvInvoke.Imread(inputPath, ImreadModes.Color)) + { + CvInvoke.Imwrite(outputPath, image); + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Image conversion took {stopwatch.ElapsedMilliseconds} ms"); +} +\end{lstlisting} + +For pixel iteration, it uses the Structure.Sketching and the code reads an image using \texttt{new Structure.Sketching.Image(imagePath)} and iterates over each pixel, calculating the grayscale value and setting the pixel value using \texttt{image.Pixels[(y * width) + x]}. The warm-up phase and main iterations are executed in a similar manner to the previous libraries, with the elapsed time for each iteration recorded using a stopwatch object. + +\begin{lstlisting}[language={[Sharp]C}, caption={Structure.Sketching Implementation (Pixel Iteration)}, label={lst:emgu_cv_structure_sketching_pixel_iteration}] +// Warm-up iterations +for (int i = 0; i < warmupIterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + var image = new Structure.Sketching.Image(imagePath); + int width = image.Width; + int height = image.Height; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + var pixel = image.Pixels[(y * width) + x]; + byte gray = (byte)((pixel.Red + pixel.Green + pixel.Blue) / 3); + image.Pixels[(y * width) + x] = new Color(gray, gray, gray, pixel.Alpha); + } + } + + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; +} + +// Main iterations +for (int i = 0; i < iterations; i++) +{ + stopwatch.Reset(); + stopwatch.Start(); + + var image = new Structure.Sketching.Image(imagePath); + int width = image.Width; + int height = image.Height; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + var pixel = image.Pixels[(y * width) + x]; + byte gray = (byte)((pixel.Red + pixel.Green + pixel.Blue) / 3); + image.Pixels[(y * width) + x] = new Color(gray, gray, gray, pixel.Alpha); + } + } + + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Pixel iteration took {stopwatch.ElapsedMilliseconds} ms"); +} +\end{lstlisting} + +Grayscale conversion is performed on each pixel by computing the average of the red, green, and blue components using the formula \texttt{(byte)((pixel.Red + pixel.Green + pixel.Blue) / 3)}. The grayscale value is then assigned to each color channel to create a grayscale image. The benchmarking process collects the results from both image conversion and pixel iteration. These results are aggregated into a tuple containing the warm-up time, the average time (excluding the warm-up phase), and the total time (including the warm-up phase). Finally, this data is used to generate an Excel file that summarizes the performance metrics. diff --git a/sections/Chapter-3-sections/Memory-Profiling.tex b/sections/Chapter-3-sections/Memory-Profiling.tex new file mode 100644 index 0000000000000000000000000000000000000000..d5f241200bcf2d46e8e18d960e9bbdc77379dc90 --- /dev/null +++ b/sections/Chapter-3-sections/Memory-Profiling.tex @@ -0,0 +1,68 @@ +\section{Memory Profiling and Performance Analysis} + +In any high-performance image processing application, it is not enough to measure raw execution time; memory consumption is equally critical. This section describes the integration of memory profiling into the benchmarking framework to provide a comprehensive view of the performance characteristics of each library and complement the time-based measurements. Using BenchmarkDotNet—a powerful tool for .NET performance analysis—we captured detailed metrics on memory allocation and garbage collection behavior. This implementation allowed us to understand the trade-offs between processing speed and resource utilization. + +The memory profiling is designed to evaluate not only the mean execution times but also the memory allocated during both image conversion and pixel iteration tasks. Using BenchmarkDotNet’s \texttt{[MemoryDiagnoser]}, \texttt{[Orderer]}, and \texttt{[RankColumn]} attributes, data on memory consumption, garbage collection events, and total allocated memory were collected for each benchmarked operation. The BenchmarkDotNet analyzer for each method by default is configured to automatically determine how many warmup and measurement iterations to run based on the workload, environment, and statistical requirements for accurate measurements. So there is no need to implement a fixed iteration count for each method manually. + +The following framework demonstrates the implementation of memory profiling and an example of how the memory diagnostics were implemented for the image conversion and pixel iteration using ImageSharp: + +\begin{lstlisting}[language={[Sharp]C}, caption={Memory Profiling and Performance Analysis (ImageSharp)}, label={lst:memory-profiling}] +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Order; +using BenchmarkDotNet.Running; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.PixelFormats; + +[MemoryDiagnoser] +[Orderer(SummaryOrderPolicy.FastestToSlowest)] +[RankColumn] +public class Benchmarks +{ + private const string InputImagePath = "./../../../../../xl1.jpg"; + private const string OutputImagePath = "./../../../../o.png"; + + [Benchmark] + public void ImageConversionBenchmark() + { + using (Image image = Image.Load(InputImagePath)) + { + using (FileStream fs = new FileStream(OutputImagePath, FileMode.Create)) + { + image.Save(fs, new PngEncoder()); + Console.WriteLine("ImageConversionBenchmark completed"); + } + } + } +\end{lstlisting} + +Same logic is used for image conversion, but there were no need for iterations and warm-up phase to be implemented manually. For configuring the \texttt{MemoryDiagnoser} results, \texttt{Orderer(SummaryOrderPolicy.FastestToSlowest)} and \texttt{RankColumn} attributes were used to order the results based on the fastest to slowest execution times and to rank the results in the summary table, respectively to provide a better and clearer view of the results. + +\begin{lstlisting}[language={[Sharp]C}, caption={Memory Profiling and Performance Analysis (ImageSharp)}, label={lst:memory-profiling}] +[Benchmark] +public void PixelIterationBenchmark() +{ + using (Image<Rgba32> image = Image.Load<Rgba32>(InputImagePath)) + { + int width = image.Width; + int height = image.Height; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + Rgba32 pixel = image[x, y]; + byte gray = (byte)((pixel.R + pixel.G + pixel.B) / 3); + image[x, y] = new Rgba32(gray, gray, gray, pixel.A); + } + } + Console.WriteLine("PixelIterationBenchmark completed"); + } +} +\end{lstlisting} + +The pixel iteration benchmark was implemented in a similar manner, with the same memory diagnostics attributes. The code snippet above demonstrates the pixel iteration benchmark for ImageSharp, where each pixel in the image is converted to grayscale. The memory diagnostics provided by BenchmarkDotNet allowed us to track the memory consumption and garbage collection events during the pixel iteration operation, providing valuable insights into the resource utilization of each library. + +This code exemplifies our approach to memory diagnostics. By annotating the benchmark class with \texttt{[MemoryDiagnoser]}, BenchmarkDotNet automatically collects data on memory usage—including the number of garbage collection (GC) events and the total allocated memory during each benchmarked operation. Similar implimentations were done for other libraries as well. + +This level of granularity provided insights that went beyond raw timing metrics, revealing, for example, that while Emgu CV might be faster in certain operations, its higher memory consumption could be a concern for applications running on memory-constrained systems. \ No newline at end of file diff --git a/sections/Chapter-3-sections/Pixel-Iteration.tex b/sections/Chapter-3-sections/Pixel-Iteration.tex new file mode 100644 index 0000000000000000000000000000000000000000..75155d9e94c341fdcfef3e1a80d1cb2bc8d9f81d --- /dev/null +++ b/sections/Chapter-3-sections/Pixel-Iteration.tex @@ -0,0 +1,82 @@ +\subsection{Pixel Iteration Benchmark Implementation} + +The pixel iteration benchmark is equally critical, as it measures the time taken to perform a basic image processing operation—converting an image to grayscale by iterating over each pixel. This benchmark simulates real-world scenarios where complex filters and effects require individual pixel manipulation. + +For ImageSharp, the implementation involves loading the image as an array of pixels, processing each pixel to compute its grayscale value, and then updating the image accordingly. The following snippet provides a glimpse into this process: + +\begin{lstlisting}[language={[Sharp]C}, caption={Image conversion benchmark implementation (ImageSharp-Testing.cs)}] +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.PixelFormats; +public class PixelIterationBenchmark +{ + public static (double warmupTime, double averageTime, double totalTime) RunBenchmark(string imagePath, int iterations) + { + long totalElapsedMilliseconds = 0; + long warmupTime = 0; + int warmupIterations = 5; + Stopwatch stopwatch = new Stopwatch(); + + // Warm-up phase for pixel iteration + for (int i = 0; i < warmupIterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + using (Image<Rgba32> image = Image.Load<Rgba32>(imagePath)) + { + int width = image.Width; + int height = image.Height; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + Rgba32 pixel = image[x, y]; + byte gray = (byte)((pixel.R + pixel.G + pixel.B) / 3); + image[x, y] = new Rgba32(gray, gray, gray, pixel.A); + } + } + } + stopwatch.Stop(); + warmupTime += stopwatch.ElapsedMilliseconds; + } + + // Main iterations to measure pixel iteration performance + for (int i = 0; i < iterations; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + using (Image<Rgba32> image = Image.Load<Rgba32>(imagePath)) + { + int width = image.Width; + int height = image.Height; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + Rgba32 pixel = image[x, y]; + byte gray = (byte)((pixel.R + pixel.G + pixel.B) / 3); + image[x, y] = new Rgba32(gray, gray, gray, pixel.A); + } + } + } + stopwatch.Stop(); + totalElapsedMilliseconds += stopwatch.ElapsedMilliseconds; + Console.WriteLine($"Iteration {i + 1}: Pixel iteration took {stopwatch.ElapsedMilliseconds} ms"); + } + + double averageTime = totalElapsedMilliseconds / (double)iterations; + double totalTime = warmupTime + totalElapsedMilliseconds; + Console.WriteLine($"Warm-up: {warmupTime} ms, Average: {averageTime} ms, Total: {totalTime} ms"); + + return (warmupTime, averageTime, totalTime); + } +} +\end{lstlisting} + +The code measures the performance of a grayscale conversion operation by iterating over each pixel of an image. As in the image conversion, it uses a timer (Stopwatch) and divides the process into two phases: a warm-up phase and a measurement phase. During the warm-up phase, the image is loaded and processed five times. This phase helps stabilize performance by mitigating any startup overheads. Each iteration involves loading the image, iterating over its width and height, reading each pixel, computing the grayscale value by averaging the red, green, and blue channels, and assigning the new grayscale value back while preserving the alpha channel. The use of the \texttt{using} statement ensures that the image is properly disposed after processing. + +In the measurement phase, the same processing occurs over a user-specified number of iterations (100 iterations). After running all iterations, the code calculates the average time per iteration and the total time including warm-up. This approach isolates the steady-state performance from any one-time overhead, resulting in more accurate measurements that reflect the true cost of pixel-by-pixel manipulations. + +The design emphasizes clear resource management, detailed timing, and separation of initialization costs from the main measurement, which are crucial when every microsecond of processing time matters in image manipulation scenarios. + +The main focus of the implementation was to capture the interplay between algorithmic efficiency and system-level resource management. Every pixel operation is executed in a closed loop, and even minor inefficiencies can accumulate over hundreds of iterations. The loop structure is designed and a stopwatch is used to measure elapsed time to matter of attention that should be paid to details during development. Because even in high-level libraries such as ImageSharp, every microsecond counts when processing large images. \ No newline at end of file diff --git a/sections/Chapter-3-sections/Result-Export.tex b/sections/Chapter-3-sections/Result-Export.tex new file mode 100644 index 0000000000000000000000000000000000000000..935131b6f04face99166339d264b52e578960718 --- /dev/null +++ b/sections/Chapter-3-sections/Result-Export.tex @@ -0,0 +1,42 @@ +\section{Result Export and Data Aggregation} + +Once the performance and memory metrics were collected, the next challenge was to present the results in a coherent and accessible manner. For this purpose, Excel was chosen as the output format due to its widespread adoption and ease of use for further analysis. \texttt{OfficeOpenXml} namespace, which is part of the EPPlus library, allows for the creation and manipulation of Excel files in .NET applications. The ExcelExporter class was implemented to aggregate the benchmark results and export them to an Excel file. + +The code snippet below illustrates how the benchmark results are aggregated and exported to an Excel file: + +\begin{lstlisting}[language={[Sharp]C}, caption={Result Export and Data Aggregation}, label={lst:result-export}] +using OfficeOpenXml; + +public class ExcelExporter +{ + public static void ExportResults(string excelOutputPath, + (double warmupTime, double averageTime, double totalTime) imageConversionResults, + (double warmupTime, double averageTime, double totalTime) pixelIterationResults) + { + using (var package = new ExcelPackage()) + { + var worksheet = package.Workbook.Worksheets.Add("Benchmark Results"); + worksheet.Cells[1, 1].Value = "Benchmark"; + worksheet.Cells[1, 2].Value = "Warm-Up Time (ms)"; + worksheet.Cells[1, 3].Value = "Average Time (ms)"; + worksheet.Cells[1, 4].Value = "Total Time (ms)"; + + worksheet.Cells[2, 1].Value = "Image Conversion"; + worksheet.Cells[2, 2].Value = imageConversionResults.warmupTime; + worksheet.Cells[2, 3].Value = imageConversionResults.averageTime; + worksheet.Cells[2, 4].Value = imageConversionResults.totalTime; + + worksheet.Cells[3, 1].Value = "Pixel Iteration"; + worksheet.Cells[3, 2].Value = pixelIterationResults.warmupTime; + worksheet.Cells[3, 3].Value = pixelIterationResults.averageTime; + worksheet.Cells[3, 4].Value = pixelIterationResults.totalTime; + + package.SaveAs(new FileInfo(excelOutputPath)); + } + } +} +\end{lstlisting} + +The ExcelExporter class creates a structured Excel file with separate sheets for each benchmark operation. The results are organized into columns for the warm-up time, average time, and total time for each operation. The resulting Excel file provides a clear and concise summary of the benchmark results, making it easy to compare the performance and memory characteristics of each library. + +By automating the process of result aggregation, the framework not only saves time but also minimizes the risk of manual errors. Each cell in the generated Excel file is carefully populated with benchmark data, and the resulting spreadsheet can be easily imported into analytical tools for further exploration. This process of exporting results serves as a bridge between the raw performance data and the actionable insights that drive decision-making in software optimization. diff --git a/sections/Chapter-3-sections/System-Architecture.tex b/sections/Chapter-3-sections/System-Architecture.tex new file mode 100644 index 0000000000000000000000000000000000000000..da12af1d682bc60fad8588d9b6b218c166984cbb --- /dev/null +++ b/sections/Chapter-3-sections/System-Architecture.tex @@ -0,0 +1,58 @@ +\section{System Architecture and Design Rationale} + +The design of our benchmarking framework was guided by the need for consistency, repeatability, and scientific severity. The system was architected to support multiple libraries through a common interface, ensuring that each library’s performance could be measured under identical conditions. At the core of our design was a twoâ€phase benchmarking process: an initial warm-up phase to account for any initialization overhead, followed by a main test phase where the actual performance metrics were recorded. + +In constructing the system, several important decisions were made. First, we employed a modular approach, separating the benchmarking routines into distinct components. This allowed us to encapsulate the logic for image conversion and pixel iteration into separate classes, each responsible for executing a series of timed iterations and logging the results. + +\begin{lstlisting}[language={[Sharp]C}, caption={Design of the benchmarking framework}] + public class ImageConversionBenchmark{ + + // Benchmarking logic for image conversion + } + public class PixelIterationBenchmark{ + + // Benchmarking logic for pixel iteration + } +\end{lstlisting} + +The architecture also included a dedicated component for result aggregation, which exported data into an Excel file using EPPlus, thereby facilitating further analysis and visualization. + +\begin{lstlisting}[language={[Sharp]C}, caption={Design of the benchmarking framework}] + using OfficeOpenXml; + + public class ExcelExporter{ + + // Logic for exporting benchmark results to an Excel sheet in a structured format + } +\end{lstlisting} + +An essential aspect of the design was the uniformity of testing. Despite the differences in methods of implementation among the libraries, the benchmarking framework was designed to abstract away these differences. Each library was integrated by implementing the same sequence of operations: reading an image from disk, processing the image (either converting its format or iterating over its pixels to apply a grayscale filter), and finally saving the processed image back to disk. This uniform methodology ensured that our performance comparisons were both fair and reproducible. + +The architecture also accounted for system-level factors such as memory management and garbage collection. For instance, in languages like C\#, where unmanaged resources must be explicitly disposed of, the design included rigorous cleanup routines to ensure that each iteration began with a clean slate. This attention to detail was crucial in obtaining accurate measurements, as any residual state from previous iterations could skew the results. + +\begin{lstlisting}[language={[Sharp]C}, caption={Design of the benchmarking framework}] + using BenchmarkDotNet.Attributes; + using BenchmarkDotNet.Running; + + class Program + { + static void Main(string[] args) + { + BenchmarkRunner.Run<Benchmarks>(); + } + } + + [MemoryDiagnoser] + public class Benchmarks{ + + [Benchmark] + public void ImageConversionBenchmark(){ + // Image conversion logic + } + + [Benchmark] + public void PixelIterationBenchmark(){ + // Pixel iteration logic + } + } +\end{lstlisting} diff --git a/sources/references.bib b/sources/references.bib new file mode 100644 index 0000000000000000000000000000000000000000..045f0d8beaade2eb17855fafb5edda8cc6565ecd --- /dev/null +++ b/sources/references.bib @@ -0,0 +1,299 @@ +@article{ferreira_generic_2024, + title = {Generic {FPGA} {Pre}-{Processing} {Image} {Library} for {Industrial} {Vision} {Systems}}, + volume = {24}, + issn = {1424-8220}, + doi = {10.3390/s24186101}, + abstract = {Currently, there is a demand for an increase in the diversity and quality of new products reaching the consumer market. This fact imposes new challenges for different industrial sectors, including processes that integrate machine vision. Hardware acceleration and improvements in processing efficiency are becoming crucial for vision-based algorithms to follow the complexity growth of future industrial systems. This article presents a generic library of pre-processing filters for execution in field-programmable gate arrays (FPGAs) to reduce the overall image processing time in vision systems. An experimental setup based on the Zybo Z7 Pcam 5C Demo project was developed and used to validate the filters described in VHDL (VHSIC hardware description language). Finally, a comparison of the execution times using GPU and CPU platforms was performed as well as an evaluation of the integration of the current work in an industrial application. The results showed a decrease in the pre-processing time from milliseconds to nanoseconds when using FPGAs.}, + language = {eng}, + number = {18}, + journal = {Sensors (Basel, Switzerland)}, + author = {Ferreira, Diogo and Moutinho, Filipe and Matos-Carvalho, João P. and Guedes, Magno and Deusdado, Pedro}, + month = sep, + year = {2024}, + pmid = {39338846}, + pmcid = {PMC11436133}, + keywords = {FPGA, GPU, industrial vision systems, pre-processing image library}, + pages = {6101}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\ZJ9KMZND\\Ferreira et al. - 2024 - Generic FPGA Pre-Processing Image Library for Industrial Vision Systems.pdf:application/pdf}, +} + +@article{vieira_performance_2024, + title = {Performance {Evaluation} of {Computer} {Vision} {Algorithms} in a {Programmable} {Logic} {Controller}: {An} {Industrial} {Case} {Study}}, + volume = {24}, + copyright = {http://creativecommons.org/licenses/by/3.0/}, + issn = {1424-8220}, + shorttitle = {Performance {Evaluation} of {Computer} {Vision} {Algorithms} in a {Programmable} {Logic} {Controller}}, + url = {https://www.mdpi.com/1424-8220/24/3/843}, + doi = {10.3390/s24030843}, + abstract = {This work evaluates the use of a programmable logic controller (PLC) from Phoenix Contact’s PLCnext ecosystem as an image processing platform. PLCnext controllers provide the functions of “classical†industrial controllers, but they are based on the Linux operating system, also allowing for the use of software tools usually associated with computers. Visual processing applications in the Python programming language using the OpenCV library are implemented in the PLC using this feature. This research is focused on evaluating the use of this PLC as an image processing platform, particularly for industrial machine vision applications. The methodology is based on comparing the PLC’s performance against a computer using standard image processing algorithms. In addition, a demonstration application based on a real-world scenario for quality control by visual inspection is presented. It is concluded that despite significant limitations in processing power, the simultaneous use of the PLC as an industrial controller and image processing platform is feasible for applications of low complexity and undemanding cycle times, providing valuable insights and benchmarks for the scientific community interested in the convergence of industrial automation and computer vision technologies.}, + language = {en}, + number = {3}, + urldate = {2025-02-16}, + journal = {Sensors}, + author = {Vieira, Rodrigo and Silva, Dino and Ribeiro, Eliseu and Perdigoto, LuÃs and Coelho, Paulo Jorge}, + month = jan, + year = {2024}, + note = {Number: 3 +Publisher: Multidisciplinary Digital Publishing Institute}, + keywords = {computer vision, OpenCV, performance benchmark, programmable logic controllers}, + pages = {843}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\QXKXLRJL\\Vieira et al. - 2024 - Performance Evaluation of Computer Vision Algorithms in a Programmable Logic Controller An Industri.pdf:application/pdf}, +} + +@article{ciora_industrial_2014, + title = {Industrial {Applications} of {Image} {Processing}}, + volume = {64}, + copyright = {http://creativecommons.org/licenses/by-nc-nd/3.0/}, + issn = {1583-7149}, + url = {https://www.sciendo.com/article/10.2478/aucts-2014-0004}, + doi = {10.2478/aucts-2014-0004}, + abstract = {Abstract + The recent advances in sensors quality and processing power provide us with excellent tools for designing more complex image processing and pattern recognition tasks. In this paper we review the existing applications of image processing and pattern recognition in industrial engineering. First we define the role of vision in an industrial. Then a dissemination of some image processing techniques, feature extraction, object recognition and industrial robotic guidance is presented. Moreover, examples of implementations of such techniques in industry are presented. Such implementations include automated visual inspection, process control, part identification, robots control. Finally, we present some conclusions regarding the investigated topics and directions for future investigation}, + language = {en}, + number = {1}, + urldate = {2025-02-16}, + journal = {ACTA Universitatis Cibiniensis}, + author = {Ciora, Radu Adrian and Simion, Carmen Mihaela}, + month = nov, + year = {2014}, + pages = {17--21}, + annote = {[TLDR] This paper defines the role of vision in an industrial, a dissemination of some image processing techniques, feature extraction, object recognition and industrial robotic guidance, and examples of implementations of such techniques in industry.}, + file = {Full Text:C\:\\Users\\SFI19\\Zotero\\storage\\ZM5USF5C\\Ciora and Simion - 2014 - Industrial Applications of Image Processing.pdf:application/pdf}, +} + +@inproceedings{kulpa_universal_1981, + address = {Berlin, Heidelberg}, + title = {Universal digital image processing systems in europe — {A} comparative survey}, + isbn = {978-3-540-38665-0}, + doi = {10.1007/3-540-10705-3_1}, + abstract = {In the paper, a selected group of eleven universal (computer based) image processing systems is surveyed and compared. They constitute a seemingly representative sample of the vast variety of such systems built in the last decade in European countries. The survey covers systems built for research purposes, either in image processing as such or for some other specific problem area, as well as more practically-oriented ones, including a commercially available routine picture analyzer. An overall classification of their general aims as well as basic parameters and features of their hardware structure, software support and application area is given.}, + language = {en}, + booktitle = {Digital {Image} {Processing} {Systems}}, + publisher = {Springer}, + author = {Kulpa, Zenon}, + editor = {Bloc, Leonard and Kulpa, Zenon}, + year = {1981}, + keywords = {Digital Holography, Image Memory, Image Processing System, Image Processor, Picture Processing}, + pages = {1--20}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\3FV26UT6\\Kulpa - 1981 - Universal digital image processing systems in europe — A comparative survey.pdf:application/pdf}, +} + +@misc{ma_new_2024, + title = {A {New} {Image} {Quality} {Database} for {Multiple} {Industrial} {Processes}}, + url = {http://arxiv.org/abs/2401.13956}, + doi = {10.48550/arXiv.2401.13956}, + abstract = {Recent years have witnessed a broader range of applications of image processing technologies in multiple industrial processes, such as smoke detection, security monitoring, and workpiece inspection. Different kinds of distortion types and levels must be introduced into an image during the processes of acquisition, compression, transmission, storage, and display, which might heavily degrade the image quality and thus strongly reduce the final display effect and clarity. To verify the reliability of existing image quality assessment methods, we establish a new industrial process image database (IPID), which contains 3000 distorted images generated by applying different levels of distortion types to each of the 50 source images. We conduct the subjective test on the aforementioned 3000 images to collect their subjective quality ratings in a well-suited laboratory environment. Finally, we perform comparison experiments on IPID database to investigate the performance of some objective image quality assessment algorithms. The experimental results show that the state-of-the-art image quality assessment methods have difficulty in predicting the quality of images that contain multiple distortion types.}, + urldate = {2025-02-16}, + publisher = {arXiv}, + author = {Ma, Xuanchao and Jiang, Yanlin and Liu, Hongyan and Zhou, Chengxu and Gu, Ke}, + month = feb, + year = {2024}, + note = {arXiv:2401.13956 [cs]}, + keywords = {Computer Science - Computer Vision and Pattern Recognition}, + file = {Preprint PDF:C\:\\Users\\SFI19\\Zotero\\storage\\BBGNJSRM\\Ma et al. - 2024 - A New Image Quality Database for Multiple Industrial Processes.pdf:application/pdf;Snapshot:C\:\\Users\\SFI19\\Zotero\\storage\\TRN3MJPN\\2401.html:text/html}, +} + +@article{chisholm_fpga-based_2020, + title = {{FPGA}-{Based} {Design} for {Real}-{Time} {Crack} {Detection} {Based} on {Particle} {Filter}}, + volume = {16}, + issn = {1941-0050}, + url = {https://ieeexplore.ieee.org/document/8888239}, + doi = {10.1109/TII.2019.2950255}, + abstract = {Due to the related hazards, costly down-time, and detection inconsistencies associated with manual visual inspection for cracks in structures, there has been an emergence of real-time systems capable of conducting inspections. Advanced robotic systems have been used for scanning structures located in remote areas or that pose significant hazards to personnel. However, due to their inherent resource limitations, the current solution is to transfer all applicable sensor data to a ground station where detection will occur at a later time, thereby preventing real-time decision based on the results. To allow on-board decision making, in this article, a crack detection particle filter is optimized for parallel computation and implemented onto an Field-programmable gate array (FPGA). This article shows that an FPGA holds distinct tradeoffs between computational speed, energy consumption, and physical footprint compared to that of traditional CPU designs, allowing for it to be an ideal system for autonomous applications.}, + number = {9}, + urldate = {2025-02-16}, + journal = {IEEE Transactions on Industrial Informatics}, + author = {Chisholm, Tim and Lins, Romulo and Givigi, Sidney}, + month = sep, + year = {2020}, + note = {Conference Name: IEEE Transactions on Industrial Informatics}, + keywords = {Autonomous application, Cameras, embedded system, Field programmable gate arrays, Hardware, Image color analysis, Image edge detection, image processing, Informatics, on-board processing, particle filter, Real-time systems}, + pages = {5703--5711}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\SEFZNXWY\\Chisholm et al. - 2020 - FPGA-Based Design for Real-Time Crack Detection Based on Particle Filter.pdf:application/pdf}, +} + +@article{perez_super-resolution_2014, + title = {Super-{Resolution} in {Plenoptic} {Cameras} {Using} {FPGAs}}, + volume = {14}, + copyright = {http://creativecommons.org/licenses/by/3.0/}, + issn = {1424-8220}, + url = {https://www.mdpi.com/1424-8220/14/5/8669}, + doi = {10.3390/s140508669}, + abstract = {Plenoptic cameras are a new type of sensor that extend the possibilities of current commercial cameras allowing 3D refocusing or the capture of 3D depths. One of the limitations of plenoptic cameras is their limited spatial resolution. In this paper we describe a fast, specialized hardware implementation of a super-resolution algorithm for plenoptic cameras. The algorithm has been designed for field programmable graphic array (FPGA) devices using VHDL (very high speed integrated circuit (VHSIC) hardware description language). With this technology, we obtain an acceleration of several orders of magnitude using its extremely high-performance signal processing capability through parallelism and pipeline architecture. The system has been developed using generics of the VHDL language. This allows a very versatile and parameterizable system. The system user can easily modify parameters such as data width, number of microlenses of the plenoptic camera, their size and shape, and the super-resolution factor. The speed of the algorithm in FPGA has been successfully compared with the execution using a conventional computer for several image sizes and different 3D refocusing planes.}, + language = {en}, + number = {5}, + urldate = {2025-02-16}, + journal = {Sensors}, + author = {Pérez, Joel and Magdaleno, Eduardo and Pérez, Fernando and RodrÃguez, Manuel and Hernández, David and Corrales, Jaime}, + month = may, + year = {2014}, + note = {Number: 5 +Publisher: Multidisciplinary Digital Publishing Institute}, + keywords = {field programmable graphic array (FPGA), lightfield, plenoptic cameras, super-resolution}, + pages = {8669--8685}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\CIH6HRCH\\Pérez et al. - 2014 - Super-Resolution in Plenoptic Cameras Using FPGAs.pdf:application/pdf}, +} + +@article{sahebi_distributed_2023, + title = {Distributed large-scale graph processing on {FPGAs}}, + volume = {10}, + issn = {2196-1115}, + url = {https://doi.org/10.1186/s40537-023-00756-x}, + doi = {10.1186/s40537-023-00756-x}, + abstract = {Processing large-scale graphs is challenging due to the nature of the computation that causes irregular memory access patterns. Managing such irregular accesses may cause significant performance degradation on both CPUs and GPUs. Thus, recent research trends propose graph processing acceleration with Field-Programmable Gate Arrays (FPGA). FPGAs are programmable hardware devices that can be fully customised to perform specific tasks in a highly parallel and efficient manner. However, FPGAs have a limited amount of on-chip memory that cannot fit the entire graph. Due to the limited device memory size, data needs to be repeatedly transferred to and from the FPGA on-chip memory, which makes data transfer time dominate over the computation time. A possible way to overcome the FPGA accelerators’ resource limitation is to engage a multi-FPGA distributed architecture and use an efficient partitioning scheme. Such a scheme aims to increase data locality and minimise communication between different partitions. This work proposes an FPGA processing engine that overlaps, hides and customises all data transfers so that the FPGA accelerator is fully utilised. This engine is integrated into a framework for using FPGA clusters and is able to use an offline partitioning method to facilitate the distribution of large-scale graphs. The proposed framework uses Hadoop at a higher level to map a graph to the underlying hardware platform. The higher layer of computation is responsible for gathering the blocks of data that have been pre-processed and stored on the host’s file system and distribute to a lower layer of computation made of FPGAs. We show how graph partitioning combined with an FPGA architecture will lead to high performance, even when the graph has Millions of vertices and Billions of edges. In the case of the PageRank algorithm, widely used for ranking the importance of nodes in a graph, compared to state-of-the-art CPU and GPU solutions, our implementation is the fastest, achieving a speedup of 13 compared to 8 and 3 respectively. Moreover, in the case of the large-scale graphs, the GPU solution fails due to memory limitations while the CPU solution achieves a speedup of 12 compared to the 26x achieved by our FPGA solution. Other state-of-the-art FPGA solutions are 28 times slower than our proposed solution. When the size of a graph limits the performance of a single FPGA device, our performance model shows that using multi-FPGAs in a distributed system can further improve the performance by about 12x. This highlights our implementation efficiency for large datasets not fitting in the on-chip memory of a hardware device.}, + number = {1}, + urldate = {2025-02-16}, + journal = {Journal of Big Data}, + author = {Sahebi, Amin and Barbone, Marco and Procaccini, Marco and Luk, Wayne and Gaydadjiev, Georgi and Giorgi, Roberto}, + month = jun, + year = {2023}, + keywords = {FPGA, Accelerators, Distributed computing, Graph processing, Grid partitioning}, + pages = {95}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\AB9AGRTA\\Sahebi et al. - 2023 - Distributed large-scale graph processing on FPGAs.pdf:application/pdf;Snapshot:C\:\\Users\\SFI19\\Zotero\\storage\\6CZYMMLI\\s40537-023-00756-x.html:text/html}, +} + +@article{reis_developments_2023, + title = {Developments of {Computer} {Vision} and {Image} {Processing}: {Methodologies} and {Applications}}, + volume = {15}, + copyright = {http://creativecommons.org/licenses/by/3.0/}, + issn = {1999-5903}, + shorttitle = {Developments of {Computer} {Vision} and {Image} {Processing}}, + url = {https://www.mdpi.com/1999-5903/15/7/233}, + doi = {10.3390/fi15070233}, + abstract = {The rapid advancement of technology has enabled a vast and ever-growing number of computer applications in real scenarios of our daily life [...]}, + language = {en}, + number = {7}, + urldate = {2025-02-16}, + journal = {Future Internet}, + author = {Reis, Manuel J. C. S.}, + month = jul, + year = {2023}, + note = {Number: 7 +Publisher: Multidisciplinary Digital Publishing Institute}, + keywords = {n/a}, + pages = {233}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\Y255DIDG\\Reis - 2023 - Developments of Computer Vision and Image Processing Methodologies and Applications.pdf:application/pdf}, +} + +@article{sandvik_comparative_2024, + title = {A {Comparative} {Literature} {Review} of {Machine} {Learning} and {Image} {Processing} {Techniques} {Used} for {Scaling} and {Grading} of {Wood} {Logs}}, + volume = {15}, + copyright = {http://creativecommons.org/licenses/by/3.0/}, + issn = {1999-4907}, + url = {https://www.mdpi.com/1999-4907/15/7/1243}, + doi = {10.3390/f15071243}, + abstract = {This literature review assesses the efficacy of image-processing techniques and machine-learning models in computer vision for wood log grading and scaling. Four searches were conducted in four scientific databases, yielding a total of 1288 results, which were narrowed down to 33 relevant studies. The studies were categorized according to their goals, including log end grading, log side grading, individual log scaling, log pile scaling, and log segmentation. The studies were compared based on the input used, choice of model, model performance, and level of autonomy. This review found a preference for images over point cloud representations for logs and an increase in camera use over laser scanners. It identified three primary model types: classical image-processing algorithms, deep learning models, and other machine learning models. However, comparing performance across studies proved challenging due to varying goals and metrics. Deep learning models showed better performance in the log pile scaling and log segmentation goal categories. Cameras were found to have become more popular over time compared to laser scanners, possibly due to stereovision cameras taking over for laser scanners for sampling point cloud datasets. Classical image-processing algorithms were consistently used, deep learning models gained prominence in 2018, and other machine learning models were used in studies published between 2010 and 2018.}, + language = {en}, + number = {7}, + urldate = {2025-02-16}, + journal = {Forests}, + author = {Sandvik, Yohann Jacob and Futsæther, Cecilia Marie and Liland, Kristian Hovde and Tomic, Oliver}, + month = jul, + year = {2024}, + note = {Number: 7 +Publisher: Multidisciplinary Digital Publishing Institute}, + keywords = {computer vision, artificial intelligence, deep learning, log grading, log scaling, wood science}, + pages = {1243}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\XU87ATGD\\Sandvik et al. - 2024 - A Comparative Literature Review of Machine Learning and Image Processing Techniques Used for Scaling.pdf:application/pdf}, +} + +@article{ziaja_benchmarking_2021, + title = {Benchmarking {Deep} {Learning} for {On}-{Board} {Space} {Applications}}, + volume = {13}, + copyright = {https://creativecommons.org/licenses/by/4.0/}, + issn = {2072-4292}, + url = {https://www.mdpi.com/2072-4292/13/19/3981}, + doi = {10.3390/rs13193981}, + abstract = {Benchmarking deep learning algorithms before deploying them in hardware-constrained execution environments, such as imaging satellites, is pivotal in real-life applications. Although a thorough and consistent benchmarking procedure can allow us to estimate the expected operational abilities of the underlying deep model, this topic remains under-researched. This paper tackles this issue and presents an end-to-end benchmarking approach for quantifying the abilities of deep learning algorithms in virtually any kind of on-board space applications. The experimental validation, performed over several state-of-the-art deep models and benchmark datasets, showed that different deep learning techniques may be effectively benchmarked using the standardized approach, which delivers quantifiable performance measures and is highly configurable. We believe that such benchmarking is crucial in delivering ready-to-use on-board artificial intelligence in emerging space applications and should become a standard tool in the deployment chain.}, + language = {en}, + number = {19}, + urldate = {2025-02-16}, + journal = {Remote Sensing}, + author = {Ziaja, Maciej and Bosowski, Piotr and Myller, Michal and Gajoch, Grzegorz and Gumiela, Michal and Protich, Jennifer and Borda, Katherine and Jayaraman, Dhivya and Dividino, Renata and Nalepa, Jakub}, + month = oct, + year = {2021}, + pages = {3981}, + file = {Full Text:C\:\\Users\\SFI19\\Zotero\\storage\\S6J3PVUF\\Ziaja et al. - 2021 - Benchmarking Deep Learning for On-Board Space Applications.pdf:application/pdf}, +} + +@article{wu_precision_2022, + title = {Precision control of polyurethane filament drafting and winding based on machine vision}, + volume = {10}, + issn = {2296-4185}, + url = {https://www.frontiersin.org/journals/bioengineering-and-biotechnology/articles/10.3389/fbioe.2022.978212/full}, + doi = {10.3389/fbioe.2022.978212}, + abstract = {{\textless}p{\textgreater}In the biomedical field, polyurethane (PU) is widely used in interventional catheters, artificial hearts, artificial blood vessels, orthopedic materials, medical adhesives, and other medical devices. In this paper, a method based on machine vision was proposed to control the drafting and winding accuracy of PU filament in order to solve the problem of centrifugal runout when the mold rotates. The centrifugal runout of the mold directly affected the preparation efficiency and quality of long artificial blood vessel by wet spinning. Through non-contact real-time detection of the filament diameter and the angle between the axis of filament and the axis of mold, the motion parameters of the two motors driving the moving platform and the drafting roller could be adjusted in real time to achieve the purpose of online real-time control of filament drafting and winding accuracy. The vision control method proposed in this paper was used to carry out the PU tube preparation experiment. The visual measurement results of the filament diameter and the included angle were compared with the manual measurement results. The average value of the diameter error is 0.0096mm, and the average value of winding angle is 0.4777°. The results proved the accuracy of the visual measuring method and testified it feasible to using machine vision instead of manual method to detect filament diameter and winding angle. Properties of the prepared PU tube were tested and analyzed. The filament diameter measured by the 3D microscope was about 0.87 mm and significantly smaller than the filament diameter before winding. This indicated that the winding was uniform, the extrusion was tight, and the adhesion was good.{\textless}/p{\textgreater}}, + language = {English}, + urldate = {2025-02-16}, + journal = {Frontiers in Bioengineering and Biotechnology}, + author = {Wu, Shilin and Yang, Huayu and Liu, Xiangyan and Jia, Rui}, + month = sep, + year = {2022}, + note = {Publisher: Frontiers}, + keywords = {Drafting Control, PU Filament, Tube preparation, Visual measurement, Winding Control}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\B6I8IJIT\\Wu et al. - 2022 - Precision control of polyurethane filament drafting and winding based on machine vision.pdf:application/pdf}, +} + +@article{zhu_machine_2022, + title = {A {Machine} {Vision} {Development} {Framework} for {Product} {Appearance} {Quality} {Inspection}}, + volume = {12}, + copyright = {http://creativecommons.org/licenses/by/3.0/}, + issn = {2076-3417}, + url = {https://www.mdpi.com/2076-3417/12/22/11565}, + doi = {10.3390/app122211565}, + abstract = {Machine vision systems are an important part of modern intelligent manufacturing systems, but due to their complexity, current vision systems are often customized and inefficiently developed. Generic closed-source machine vision development software is often poorly targeted. To meet the extensive needs of product appearance quality inspection in industrial production and to improve the development efficiency and reliability of such systems, this paper designs and implements a general machine vision software framework. This framework is easy to adapt to different hardware devices for secondary development, reducing the workload in generic functional modules and program architecture design, which allows developers to focus on the design and implementation of image-processing algorithms. Based on the MVP software design principles, the framework abstracts and implements the modules common to machine vision-based product appearance quality inspection systems, such as user management, inspection configuration, task management, image acquisition, database configuration, GUI, multi-threaded architecture, IO communication, etc. Using this framework and adding the secondary development of image-processing algorithms, we successfully apply the framework to the quality inspection of the surface defects of bolts.}, + language = {en}, + number = {22}, + urldate = {2025-02-16}, + journal = {Applied Sciences}, + author = {Zhu, Qiuyu and Zhang, Yunxiao and Luan, Jianbing and Hu, Liheng}, + month = jan, + year = {2022}, + note = {Number: 22 +Publisher: Multidisciplinary Digital Publishing Institute}, + keywords = {appearance quality, industrial inspection, machine vision, software framework}, + pages = {11565}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\FRCDALEP\\Zhu et al. - 2022 - A Machine Vision Development Framework for Product Appearance Quality Inspection.pdf:application/pdf}, +} + +@article{sardar_role_2012, + title = {A role of computer system for comparative analysis using image processing to promote agriculture business}, + url = {https://www.semanticscholar.org/paper/A-role-of-computer-system-for-comparative-analysis-Sardar/6e2fd48a1025b68951f511abe05f8451f753eb47}, + abstract = {The computer system play a very important role using image processing for agriculture business using technological approaches for food processing \& food engineering during production in agriculture. In this research paper a updated of hassu algorithm is proposed to quality analysis and detect defects of fruits(i.e. Guava, orange, desi berry) further which can be implemted for grading and sorting of a particular fruit (i.e. same category) by its visual color of surface using the non-destructive technique to automated quality verification systems for agricultural products with the help of digital images which involve visual examination and inspection of color, size, shape, defects and texture are highlighted further for image processing. So here color is the key and unique attribute for determine the quality, where intensity value of pixel of digital image is recognize using MATLAB Keyword: fruits, color, pixel value, camera}, + urldate = {2025-02-16}, + journal = {International journal of engineering research and technology}, + author = {Sardar, Hassan}, + month = nov, + year = {2012}, + annote = {[TLDR] A updated of hassu algorithm is proposed to quality analysis and detect defects of fruits and intensity value of pixel of digital image is recognize using MATLAB Keyword: fruits, color, pixel value, camera.}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\58SULJWP\\Sardar - 2012 - A role of computer system for comparative analysis using image processing to promote agriculture bus.pdf:application/pdf}, +} + +@article{lai_image_2001, + title = {Image {Processing} {Libraries}}, + abstract = {There are a wide variety of image process-ing library implementations. Three imple-mentations are discussed in this paper, in the hope of showing the diverse nature of im-age processing libraries. Datacube provides a hardware and vendor-specific image pro-cessing library, known as ImageFlow, devel-oped to support their pipeling image process-ing hardware card. Vector, Signal and Image Processing Library (VSIPL) is a hardware-neutral approach with a focus on portabil-ity. Finally Vision with Generic Algorithms (VIGRA) is built on the principles of generic programming and is therefore flexible without incurring large speed penalties.}, + author = {Lai, Bing-Chang and {Phillip} and McKerrow, Phillip}, + month = jan, + year = {2001}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\5F9V4RSE\\Lai et al. - 2001 - Image Processing Libraries.pdf:application/pdf}, +} + +@article{rao_comparative_2023, + title = {A {Comparative} {Analysis} of {Deep} {Learning} {Frameworks} and {Libraries}}, + volume = {11}, + copyright = {Copyright (c) 2023 M. Nagabhushana Rao}, + issn = {2147-6799}, + url = {https://ijisae.org/index.php/IJISAE/article/view/2707}, + abstract = {Deep learning has become a popular approach for solving complex problems in various fields, including image recognition, natural language processing, and speech recognition. As a result, numerous deep learning frameworks and libraries have been developed, each with its unique strengths and weaknesses. Choosing the right framework and library for a given application is essential for achieving optimal performance and accuracy. This study aims to provide a comparative analysis of deep learning frameworks and libraries based on their ease of use, computational efficiency, flexibility, and performance. The study evaluates six popular deep-learning frameworks and libraries, including TensorFlow, Keras, PyTorch, Caffe, MXNet, and Theano. The evaluation process includes the implementation of deep learning models using each framework, training, and testing on benchmark datasets, and collecting evaluation metrics. The study uses several benchmark datasets, including CIFAR-10, ImageNet, and MNIST. The study compares the evaluated deep learning frameworks and libraries in terms of their ease of use, computational efficiency, flexibility, and performance. The study also discusses the impact of the evaluated deep learning frameworks and libraries on the performance and accuracy of the developed models, highlighting the trade-offs and limitations of each framework. The results show that TensorFlow and PyTorch are the most popular and widely used frameworks due to their flexibility, ease of use, and strong community support. This study has several implications for practitioners in the field of deep learning, highlighting the importance of the selection of the appropriate framework and library for the development of successful models. The study also contributes new insights and knowledge to the field of deep learning and suggests future research directions for improving and extending the research in new directions. Overall, this study provides valuable information for researchers and practitioners seeking to evaluate and select the best deep-learning framework and library for their specific needs.}, + language = {en}, + number = {2s}, + urldate = {2025-02-16}, + journal = {International Journal of Intelligent Systems and Applications in Engineering}, + author = {Rao, M. Nagabhushana}, + month = jan, + year = {2023}, + note = {Number: 2s}, + keywords = {TensorFlow}, + pages = {337--342}, + file = {Full Text PDF:C\:\\Users\\SFI19\\Zotero\\storage\\25G2NS2A\\Rao - 2023 - A Comparative Analysis of Deep Learning Frameworks and Libraries.pdf:application/pdf}, +}