To understand why OMR is so neglected is because most people widely underestimate the difficulty of the task. It has a specific blend of the most extreme shapes combined with an extremely complicated graphical grammar...
73 karma · joined May 10, 2017
To understand why OMR is so neglected is because most people widely underestimate the difficulty of the task. It has a specific blend of the most extreme shapes combined with an extremely complicated graphical grammar...
Welcome to SWI-Prolog (threaded, 64 bits, version 9.2.9)
?- use_module(library(clpBNR)).
% *** clpBNR v0.12.2 ***.
true.
?- {TotalOwed == TotalTax - TotalPayments}.
TotalOwed::real(-1.0Inf, 1.0Inf),
TotalTax::real(-1.0Inf, 1.0Inf),
TotalPayments::real(-1.0Inf, 1.0Inf).
?- {TotalOwed == TotalTax - TotalPayments}, TotalTax = 10, TotalPayments = 5.
TotalOwed = TotalPayments, TotalPayments = 5,
TotalTax = 10.
If you restrict yourself to the pure subset of prolog, you can even express complicated computation involving conditions or recusions.
However, this means that your graph is now encoded into the prolog code itself, which is harder to manipulate, but still fully manipulable in prolog itself.But the author talks about xml as an interchange format which is indeed better than prolog code...
In the comparative table, they claim that conda doesn't support:
* lock file: which is false, you can freeze your environment
* task runner: I don't need my package manager to be a task runner
* project management: You can do 1 env per project ? I don't see the problem here...
So no, please, just use conda/mamba and conda-forge.
I think the reason this method is not popular is that there are still many ways to encode a semantic object graphically. A sentence can be broken down into words or letters. Table lines can be formed from multiple smaller lines, etc. But, as mentioned by the parent, rule based systems works reasonably well for reasonably focused problems. But you will never have a general purpose extractor since rules needs to be written by humans.
[1] https://poppler.freedesktop.org/ [2] https://gitlab.freedesktop.org/poppler/poppler/-/blob/master...
I have tried to bring that to the prolog world [2] but I don't think my fellow prolog programmers are very receptive to the idea ^^.
* of its ability to store unit system data as code
* unit conversion is an iterative deepening depth first search
* manipulating symbolic arithmetic is so easy
Unfortunately, it requires users to compile swi-prolog for source because the library is using some unreleased features. If anyone would like to test and report some feedback, I would be truly grateful !
At the time, I was a bit lost with their custom testing framework, but was very imprest by the ease of contributing to one of the most successful open-source project out there.
I now understand why. It is because of their rules around testing and readability (and the friendly attitude of Daniel Stenberg) that a novice like me managed to do it.
[1] https://github.com/kwon-young/units
[2] https://github.com/kwon-young/units/blob/master/examples/spe...
And some example uses: https://github.com/kwon-young/array/blob/master/kernel.pl#L5...
It's been months I've been stuck on the description of note groups because of the insanely complex 2D semantics.
However, the process seems quite complicated and slow, asking you to draw control points and all that.
Microscope pictures have the particularity that there are nearly no deformation to the image but you have a lot of them, so you want the process to be as automatic as possible. That was the goal of my tool, make the simplest gui anf process possible for the task at hand.
I can confirm what the post affirms that panorama stitcher softwares are not able to do the job. But what I found was that the opencv Stitcher class can do this perfectly out of the box. Unfortunately, there was no existing gui for the class at the time, so I quickly made one in 3 days: https://github.com/kwon-young/ImageStitcher
It would have been nice if the post had compared it's approach to the Stitcher class. Maybe the number of images or the size of the final image or the stitching error control cannot be sufficiently controled with the Stitcher class ?
:- set_prolog_flag(double_quotes, codes).
text("Vixen should be behind Rudolph, Prancer and Dasher, whilst Vixen should be in front of Dancer and Comet. Dancer should be behind Donder, Blitzen and Rudolph. Comet should be behind Cupid, Prancer and Rudolph. Donder should be behind Comet, Vixen, Dasher, Prancer and Cupid. Cupid should be in front of Comet, Blitzen, Vixen, Dancer and Rudolph. Prancer should be in front of Blitzen, Donder and Cupid. Blitzen should be behind Cupid but in front of Dancer, Vixen and Donder. Rudolph should be behind Prancer but in front of Dasher, Dancer and Donder. Finally, Dasher should be behind Prancer but in front of Blitzen, Dancer and Vixen.").
space -->
" ".
reindeer('Blitzen') -->
"Blitzen".
reindeer('Comet') -->
"Comet".
reindeer('Cupid') -->
"Cupid".
reindeer('Dancer') -->
"Dancer".
reindeer('Dasher') -->
"Dasher".
reindeer('Donder') -->
"Donder".
reindeer('Prancer') -->
"Prancer".
reindeer('Rudolph') -->
"Rudolph".
reindeer('Vixen') -->
"Vixen".
complement(S, P, [[S, P, Reindeer] | R], R) -->
reindeer(Reindeer).
sep -->
", ".
sep -->
" and ".
list(Pred, Sep, S1, S3) -->
call(Pred, S1, S2),
list_next(Pred, Sep, S2, S3).
list_next(Pred, Sep, S1, S3) -->
Sep,
call(Pred, S1, S2),
list_next(Pred, Sep, S2, S3).
list_next(_, _, S, S) -->
[].
position(>) -->
"behind".
position(<) -->
"in front of".
text(S) -->
list(proposition, space, S, S2),
space,
last_sentence(S2, []).
last_sentence(S1, S2) -->
"Finally, ",
proposition(S1, S2).
proposition(S1, S3) -->
proposition(R, S1, S2),
inverse_proposition(R, S2, S3),
".".
proposition(R, S1, S2) -->
reindeer(R),
" should be ",
position_list(R, S1, S2).
position_list(R, S1, S2) -->
position(P),
space,
list(complement(R, P), sep, S1, S2).
inverse_proposition(R, S1, S2) -->
" but ",
position_list(R, S1, S2).
inverse_proposition(R, S1, S2) -->
", whilst ",
proposition(R, S1, S2).
inverse_proposition(_, S, S) -->
[].
:- table(follows/3).
follows(R1, R2, Pairs) :-
member([R1, >, R2], Pairs).
follows(R1, R2, Pairs) :-
member([R2, <, R1], Pairs).
follows(R1, R3, Pairs) :-
follows(R1, R2, Pairs),
follows(R2, R3, Pairs).
order([X | L], Pairs) :-
order(L, X, Pairs).
order([], _, _).
order([Y | L], X, Pairs) :-
follows(Y, X, Pairs),
order(L, Y, Pairs).
And we can solve the riddle with: ?- text(T), phrase(text(Pairs), T), length(L, 9), order(L, Pairs).
T = [86, 105, 120, 101, 110, 32, 115, 104, 111|...],
Pairs = [['Vixen', >, 'Rudolph'], ['Vixen', >, 'Prancer'], ['Vixen', >, 'Dasher'], ['Vixen', <
, 'Dancer'], ['Vixen', <, 'Comet'], ['Dancer', >, 'Donder'], ['Dancer', >|...], ['Dancer'|...]
, [...|...]|...],
L = ['Prancer', 'Cupid', 'Rudolph', 'Dasher', 'Blitzen', 'Vixen', 'Comet', 'Donder', 'Dancer']
One nice thing we can do with this grammar is that we can also generate the text from a list of constraints: ?- Pairs = [['Prancer', <, 'Cupid'], ['Cupid', <, 'Rudolph']], phrase(text(Pairs), T), string_codes(S, T).
Pairs = [['Prancer', <, 'Cupid'], ['Cupid', <, 'Rudolph']],
T = [80, 114, 97, 110, 99, 101, 114, 32, 115|...],
S = "Prancer should be in front of Cupid. Finally, Cupid should be in front of Rudolph." .I'm happy to answer any questions you might have.
Just a note: this project is not at all in a shareable state (no documentation, incomplete workflow). It is just a very rough proof of concept.
His setup only has a simple microscope camera that can stream a video to an old windows xp pc with a hardware/software combination...
I found out that the out of the box opencv Stitcher [1] class is perfect for that but nobody seems to have made a GUI out of it.
So, I've spent two days making an extremely simple proof of concept of a Qt Gui [2].
The majority of the time was spent trying to use GitHub Action to automatically build an executable...
If you go see in the release section, there is a tag with a prebuilt binary.
[1]: https://docs.opencv.org/4.x/d8/d19/tutorial_stitcher.html