@afre : To me the correct terminology for kernels is something like:
Kernels defined on finite domain :
size : Size of the kernel, for instance size=7 means a 7x7 kernel.
radius : Radius of the kernel, which means an equivalent size = 2 * radius + 1. You can’t have even-sized kernel when specifying a radius.
Kernel defined on infinite domain (usually gaussian) :
std_deviation : standard deviation (sigma) used in the gaussian function. Almost 100% of the significant values of the gaussian function are located in range |x|<3.5 * radius (see 68–95–99.7 rule - Wikipedia), so you can get an idea of what the equivalent radius could be, if the kernel had a finite domain.
It may happen that this terminology is not the one used in some commands (I’ve not checked all of them ), but this is probably how it should be done.
Well, yes, as the number of shortcut is quite limited, we can always construct this list manually
+3d (+): Shortcut for command 'add3d'
/3d (+): Shortcut for command 'div3d'
*3d (+): Shortcut for command 'mul3d'
-3d (+): Shortcut for command 'sub3d'
ac : Shortcut for command 'apply_channels'
apc : Shortcut for command 'apply_parallel_channels'
apo : Shortcut for command 'apply_parallel_overlap'
ap : Shortcut for command 'apply_parallel'
a (+): Shortcut for command 'append'
b (+): Shortcut for command 'blur'
c3d : Shortcut for command 'center3d'
col3d (+): Shortcut for command 'color3d'
c (+): Shortcut for command 'cut'
d0 : Shortcut for command 'display0'
d3d (+): Shortcut for command 'display3d'
da : Shortcut for command 'display_array'
db3d (+): Shortcut for command 'double3d'
dfft : Shortcut for command 'display_fft'
dg : Shortcut for command 'display_graph'
dh : Shortcut for command 'display_histogram'
dp0 : Shortcut for command 'display_parallel0'
dp : Shortcut for command 'display_parallel'
dq : Shortcut for command 'display_quiver'
drgba : Shortcut for command 'display_rgba'
d (+): Shortcut for command 'display'
dt : Shortcut for command 'display_tensors'
dw : Shortcut for command 'display_warp'
endl (+): Shortcut for command 'endlocal'
e (+): Shortcut for command 'echo'
f3d (+): Shortcut for command 'focale3d'
fc : Shortcut for command 'fill_color'
fi (+): Shortcut for command 'endif'
frame : Shortcut for command 'frame_xy'
f (+): Shortcut for command 'fill'
g (+): Shortcut for command 'gradient'
h : Shortcut for command 'help'
ig : Shortcut for command 'input_glob'
ir : Shortcut for command 'inrange'
i (+): Shortcut for command 'input'
j3d (+): Shortcut for command 'object3d'
j (+): Shortcut for command 'image'
k (+): Shortcut for command 'keep'
l3d (+): Shortcut for command 'light3d'
l (+): Shortcut for command 'local'
m3d (+): Shortcut for command 'mode3d'
md3d (+): Shortcut for command 'moded3d'
m (+): Shortcut for command 'command'
m/ (+): Shortcut for command 'mdiv'
m* (+): Shortcut for command 'mmul'
mv (+): Shortcut for command 'move'
n3d : Shortcut for command 'normalize3d'
nm (+): Shortcut for command 'name'
n (+): Shortcut for command 'normalize'
o3d (+): Shortcut for command 'opacity3d'
on : Shortcut for command 'outputn'
op : Shortcut for command 'outputp'
o (+): Shortcut for command 'output'
ow : Shortcut for command 'outputw'
ox : Shortcut for command 'outputx'
p3d (+): Shortcut for command 'primitives3d'
p (+): Shortcut for command 'print'
q (+): Shortcut for command 'quit'
r2dx : Shortcut for command 'resize2dx'
r2dy : Shortcut for command 'resize2dy'
r3d (+): Shortcut for command 'rotate3d'
r3dx : Shortcut for command 'resize3dx'
r3dy : Shortcut for command 'resize3dy'
r3dz : Shortcut for command 'resize3dz'
rm (+): Shortcut for command 'remove'
rr2d : Shortcut for command 'resize_ratio2d'
r (+): Shortcut for command 'resize'
rv3d (+): Shortcut for command 'reverse3d'
rv (+): Shortcut for command 'reverse'
s3d (+): Shortcut for command 'split3d'
+ (+): Shortcut for command 'add'
& (+): Shortcut for command 'and'
<< (+): Shortcut for command 'bsl'
>> (+): Shortcut for command 'bsr'
/ (+): Shortcut for command 'div'
== (+): Shortcut for command 'eq'
>= (+): Shortcut for command 'ge'
> (+): Shortcut for command 'gt'
<= (+): Shortcut for command 'le'
< (+): Shortcut for command 'lt'
% (+): Shortcut for command 'mod'
* (+): Shortcut for command 'mul'
!= (+): Shortcut for command 'neq'
| (+): Shortcut for command 'or'
^ (+): Shortcut for command 'pow'
= (+): Shortcut for command 'set'
- (+): Shortcut for command 'sub'
sh (+): Shortcut for command 'shared'
sl3d (+): Shortcut for command 'specl3d'
sp : Shortcut for command 'sample'
ss3d (+): Shortcut for command 'specs3d'
s (+): Shortcut for command 'split'
t3d (+): Shortcut for command 'texturize3d'
to : Shortcut for command 'text_outline'
t (+): Shortcut for command 'text'
up : Shortcut for command 'update'
u (+): Shortcut for command 'status'
v (+): Shortcut for command 'verbose'
w (+): Shortcut for command 'window'
x (+): Shortcut for command 'exec'
y (+): Shortcut for command 'unroll'
z (+): Shortcut for command 'crop'
That’s very helpful, thanks. Can I ask that you make the list a part of your standard documentation? Perhaps as a file that you maintain, so other folk can download as and when needed?
What if I wanted to do this without local? Something like b#$> doesn’t work. I am asking because I cannot use local in some cases; e.g., when iterating over pixels like for MSE but I still want to echo the input names with the respective MSE values.
That’s right, I flipped the items by mistake to {feature,ind}!
What is the simplest way to store values and strings into a vector? Two ways demonstrated by @garagecoderpost #9 and @David_Tschumperlepost #12 of the other thread seem over complicated (or I am just not used to doing it that way). Here is an example. Goal: make each line a vector element in s and echo the fifth element of s somewhere down the pipeline.
For that, I usually use numbered variables as $lineN (where N is an integer) to simulate an array of variables. It’s quite easy to manage. For instance, the following code read each non-empty line of a text file:
read_lines:
verbose -
input raw:"$1",uchar # Get ascii values of the file as a new image of data in [0,255].
split -,{'\n'} # Decompose as lines (and discard '\n').
repeat $! line$>={$>,t} done # Assign line content to numbered variables
remove
verbose +
echo[] "Fifth non-empty line : "$line4
echo[] "First 5 non-empty-lines :"
repeat 5 echo[] " ["{1+$>}"] = "${line$>} done
Then, using it like this : $ gmic read_lines README gives:
Thanks: read_lines explains a lot. The part that I was missing was split -,{'\n'}. I don’t quite know when to use echo[] and echo_stdout though. Besides error versus standard output, echo[] appears to require less quoting ", so maybe I will stick with that one. I guess my choice would affect the logs…? I also discovered the string command, so I could do
Next question. I have been playing around with norms and deciding what I could use them for. I wanted to try calculating the Frobenius norm but I don’t know a simple way to add all the elements of a matrix. norm is sqr compose_channels + sqrt; I guess that is supposed to be done before compose_channels +… Wait, are we already calculating the f-norm since an image is already a matrix?
I’m not sure how you define this for multi channel images because it’s equivalent to euclidean norm of an m x n matrix treated as a vector (i.e. output is a scalar). In other words sum the squares of the elements then take the square root of that. For single channel image it would just be:
If that is true, then a matrix would be a line of pixels… I think a more useful application might be to move a f-norm window over an image for each channel but I don’t know how to do that yet . Sure enough, Google Scholar does yield papers where people use norms as a filter.
…
Speaking of image filtering, one exercise would be to write a command that passes an arbitrary kernel (given by user) through an image like the Convolution matrix filter in GIMP, but it might not be able to do a f-norm, because I don’t know what the matrix is…?
sp dog
sqr
(1) # a single pixel image with value 1
resize. 5,5
convolve.. . # convolve input by kernel
rm.
sqrt
For larger kernels you could do that with the boxfilter command (approximate but fast), there’s also the option of using the math parser. It’s very easy to specify a kernel by image values (here I use the backslash to escape newline for clarity):
I need some ideas to get started with finding edges. There are so many commands that I don’t know where to start. So far, I have only made threshold images based on Boolean expressions. Not necessarily but something like this would be nice:
Source: Images borrowed from this paper.
…
What I have so far. Not great but a start .
edge_test0:
l50_ 1 # L* channel from L*a*b* D50
laplacian - {im}
fill i<ia+sqrt(iv)&&i>ia-sqrt(iv)
negate 1
Edge detection is a large subject in itself, but the one I usually end up using is gradient_norm. Combined with an exponent or a threshold (of which there are many, perhaps give ‘otsu’ a try) it’s quite hard to beat in general situations, for such a simple operation.
Used gradient_norm before and wanted to try laplacian. Otsu is cleaner overall but may ignore weaker edges. Turns out it is still the right one to use:
Speaking of convolution, I came across Sharpening Images with Edge Detection in the Imagemagick docs. I am having trouble understanding and reproducing the first command.
Hint: jump here for details on -define and here for -morphology. Actually, 0x2 might have to do with -gaussian-blur. I am not quite sure; I haven’t used IM in a while. (@snibgo, maybe you could help me with the explanation.)
Hmm those docs have some suspect descriptions of so-called ‘LoG’. I assume the -define part is setting parameters for the convolution (I never use imagemagick). The idea of that kernel is to save doing two separate steps (blur then laplacian) by using laplacian of a gaussian as the kernel: