HN user

kwon-young

73 karma
Posts3
Comments20
View on HN

So, the format for musicologist and researcher in music is the MEI format: https://music-encoding.org/ for which the reference engraver is verovio: https://www.verovio.org/index.xhtml Note that verovio is able to engrave in svg format while keeping a maximum of information from the original mei score, meaning that you can extract enough metadata to create an actual detection dataset for a deep learning model. This is my horrible hacked up script that will create a coco dataset from a set of scores engraved with verovio: https://github.com/kwon-young/music/blob/main/svg2pl.py I have published a synthetic music score dataset from this: https://www.kaggle.com/datasets/kwonyoungchoi/trompa-coco/da... I anyone wants to try and fit a detector on top is welcome :)

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...

XML Is a Cheap DSL 4 months ago

The article mentions prolog but doesn't mention you can use constraints to fully express his computation graph. My prefered library is clpBNR which has powerful constraints over boolean, integers and floats:

  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...

I don't see the advantage ?

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.

In my opinion, anything that touch compiled packages like pytorch should be packaged with conda/mamba on conda-forge. I found it is the only package manager for python which will reliably detect my hardware and install the correct version of every dependency.

Just to illustrate this point, poppler [1] (which is the most popular pdf renderer in open source) has a little tool called pdf2cairo [2] which can render a pdf into a svg. This means you can delegate all pdf rendering to poppler and only work with actual graphical objects to extract semantics.

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...

Use Your Type System 12 months ago

This reminds me of the mp-units [1] library which aims to solve this problem focusing on the physical quantities. The use of strong quantities means that you can have both safety and complex conversion logic handled automatically, while having generic code not tied to single set of units.

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 ^^.

[1] https://mpusz.github.io/mp-units/latest/

[2] https://github.com/kwon-young/units

I am working on a unit-aware arithmetic library for swi-prolog (1) modeled after the c++ mp-units library (2). Turns out prolog is really well suited for this because:

* 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 !

1. https://github.com/kwon-young/units

2. https://mpusz.github.io/mp-units/latest/

Curl is one of the very few projects I managed to contribute to with a very simple PR.

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.

I have recently started working on a swi-prolog library for unit aware arithmetic[1]. It is still very bare bone (especially in documentation), but I started writing some examples[2] to showcase the library. It is essentially a port of the mp-units[3] library in c++. It was a lot of fun, and I found prolog especially well suited for manipulating symbolic representation of units and quantities.

[1] https://github.com/kwon-young/units

[2] https://github.com/kwon-young/units/blob/master/examples/spe...

[3] https://mpusz.github.io/mp-units/latest/

C Plus Prolog 1 year ago

Funny how we can stumble on the same idea from a different perspective. In my case, I wanted to generate efficient C code for an array library written in prolog. The logical solution was to manipulate a C ast from prolog, but since a lot of the ast needed to be written by me, I chose to make it very similar to the original C syntax. Here is the grammar generating tokens from the ast and then c code from tokens: https://github.com/kwon-young/array/blob/master/c99.pl

And some example uses: https://github.com/kwon-young/array/blob/master/kernel.pl#L5...

I'm working on a pure SWI-Prolog grammar to describe the modern music notation. The end goal being to be able to do the last step of Optical Music Recognition and generate the final music score (in the MEI) from a set of graphical primitives: https://github.com/kwon-young/music

It's been months I've been stuck on the description of note groups because of the insanely complex 2D semantics.

I don't recall finding hugin when I did my (short) research on image stitching tool. Thanks to you, I've read the scanned image stitching documentation and I suppose it could work.

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.

Yeah, I should really try to improve it... But it was just 3 days hacking to put a frontend on the opencv Stitch class and produce an exe that my dad could use.

A few years ago, my dad working in chips control quality asked me how to do exactly this but with images from optical microscopes.

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 ?

Prolog was made to parse text, so shouldn't we derive the constraints from the text itself with a DCG ?

  :- 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." .

Wow, I never would have imagined that my project would be shared on hacker news by Markus Triska!

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.

In my case, my dad needed a Gui for stitching microscope images and he told me that none of the panorama stitching Guis were working for him.

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

[2] https://github.com/kwon-young/ImageStitcher