Il problema con la sovrastima della lunghezza per le linee diagonali deriva interamente dall'approccio che stai prendendo, vale a dire contare "i bordi della griglia di pixel che hanno colori diversi su ciascun lato" e dichiarare la somma come una lunghezza del contorno. Questi due non sono equivalenti in generale.
Essenzialmente ti stai limitando a calcolare le distanze "sulla griglia" anziché le distanze Euclide ("diretta") o "spianata per più punti" tra i bordi reali del contorno (non i "bordi" della griglia). La ragione per cui ritieni che il tuo approccio sia impreciso per le linee diagonali è perché i tuoi criteri di accuratezza hanno a che fare con la precisione sub-pixel, mentre nel tuo algoritmo stai operando su un livello di precisione dei pixel ("bordi" della griglia rasterizzata).
Perché non applicare prima il rilevamento dei bordi e ottenere un elenco di bordi con le coordinate dei sub-pixel (è possibile applicare qualsiasi algoritmo di rilevamento dei bordi sub-pixel). Il risultato di questo passaggio sarà una lista di coppie di doppi. Questo passaggio trasformerà il tuo problema in un dominio sub-pixel, in cui puoi calcolare le distanze e soddisfare i tuoi criteri di precisione.
Dopo aver eseguito il drill down fino ai bordi a livello sub-pixel, abbiamo due opzioni principali:
- per calcolare la somma delle distanze euclidee tra i bordi successivi. Ci darà una lunghezza accettabile di countour dato che abbiamo scelto un algoritmo di rilevamento dei bordi decente;
- per collegare i bordi in modo uniforme (ad esempio B-spline) e calcolare una somma di lunghezze arco tra i bordi successivi in base alla funzione interpolante che hai selezionato.
UPDATE
L'approccio semplificato per il primo passo sarebbe quello di scegliere un punto medio sub-pixel dei tuoi "bordi" idonei della griglia rasterizzata e dichiararlo al centro del bordo. Da lì si procede con il calcolo delle distanze - anche con le distanze euclidee tra i punti centrali si otterrà un risultato molto accurato quindi contando i "bordi" eludibili della griglia rasterizzata. Almeno il problema "sovrastima per fattore di sqrt (2)" per le linee diagonali sarà risolto. Spero che ti aiuti.