Zhang-Suen thinning algorithm: Difference between revisions

m
syntax highlighting fixup automation
m (Added syntax highlighting (working from the back of the task list).)
m (syntax highlighting fixup automation)
Line 111:
{{trans|Python}}
 
<syntaxhighlight lang="11l">V beforeTxt = |‘1100111
1100111
1100111
Line 263:
 
=={{header|Action!}}==
<syntaxhighlight lang=Action"action!">PROC DrawImage(BYTE ARRAY image BYTE x,y,width,height)
BYTE i,j
BYTE POINTER ptr
Line 398:
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">-- Params:
-- List of lists (rows) of "pixel" values.
-- Record indicating the values representing black and white.
Line 503:
00000000000000000000000000000000"</pre>
Alternative demo:
<syntaxhighlight lang="applescript">on demo()
set pattern to "
################# #############
Line 556:
{{works with|AutoHotkey_L}}
Reads input from a text file and writes output to a different text file (first creating the file, if necessary).
<syntaxhighlight lang=AutoHotkey"autohotkey">FileIn := A_ScriptDir "\Zhang-Suen.txt"
FileOut := A_ScriptDir "\NewFile.txt"
 
Line 655:
</pre>
The images before and after thinning are also printed on the console.
<syntaxhighlight lang=C"c">
#include<stdlib.h>
#include<stdio.h>
Line 886:
=={{header|C++}}==
Compiled with --std=c++14
<syntaxhighlight lang=CPP"cpp">#include <iostream>
#include <string>
#include <sstream>
Line 1,201:
=={{header|D}}==
This uses the module from the Bitmap Task. And it performs no heap allocations.
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.functional,
std.typecons, std.typetuple, bitmap;
 
Line 1,429:
ELENA 5.0 :
{{trans|Java}}
<syntaxhighlight lang="elena">import system'collections;
import system'routines;
import extensions;
Line 1,620:
=={{header|Elixir}}==
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule ZhangSuen do
@neighbours [{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}] # 8 neighbours
Line 1,772:
 
=={{header|Fortran}}==
With F90 came standardisation of a variety of array manipulation facilities. Since the image array is to be inspected as a whole then adjusted rather than adjusted step-by-step as it is inspected, the first thought was to employ the special facility of the FOR ALL statement, which is that in an expression such as <syntaxhighlight lang=Fortarn"fortarn">FOR ALL (i = 2:n - 1) A(i) = (A(i - 1) + A(i) + A(i + 1))/3</syntaxhighlight> all right-hand-side expressions will be evaluated with the original values of the array, while in the less special array assignment <syntaxhighlight lang=Fortran"fortran">A(2:N - 1) = (A(1:N - 2) + A(2:N - 1) + A(3:N))/3</syntaxhighlight> as in the case of the equivalent DO-loop, the processing will be with a mixture of old and new values as the loop proceeds.
 
So, that suggests something like <syntaxhighlight lang=Fortran"fortran"> FOR ALL (I = 2:N - 1, J = 2:M - 1)
WHERE(DOT(I,J) .NE. 0) DOT(I,J) = ADJUST(DOT,I,J)</syntaxhighlight>
This requires function ADJUST to be a "pure" function, and they are not supposed to perpetrate side effects, such as one reporting that any adjustment was made. Nor is it clear that array DOT must be presented as a parameter either as the entire array or as element DOT(i,j), or if not, that it can be global to function ADJUST - which would also be an impurity - and for that matter, variables I and J could be global also...
Line 1,780:
Instead, thought turned to more closely following the task specification, which involves producing a list of elements to be adjusted after an inspection pass. Given that array DOT is two-dimensional, it would be nice if an element could be indexed via an expression such as <code>DOT(INDEX)</code> where INDEX was an array of two elements with INDEX(1) = i, and INDEX(2) = j, so as to access DOT(i,j) If this were possible, then obviously one could hope that array INDEX could be extended so as to store the multiple elements of a list of such locations to access, with a view to <code>DOT(INDEX(1:n)) = 0</code> adjusting the image.
 
Alas, such a syntax form is not accommodated. However, F90 also introduced the ability to define and use compound data types, such as the type PLACE as used below. It is not possible to define a type of a special, recognised form, such as say "SUBSCRIPT LIST" that can be used as dreamt of above, so the components are just ordinary variables. Two ordinary arrays could be used, one for each of the two subscripts, or a compound type could be devised in a hint towards self-documentation. Thus, <syntaxhighlight lang=Fortran"fortran"> DOT(WHACK(1:WHACKCOUNT).I,WHACK(1:WHACKCOUNT).J) = 0</syntaxhighlight>
 
But it doesn't work... After a fair amount of head scratching, not at all assisted by the woolly generalities and inane examples of the compiler's "help" collection, it became apparent that the expression did not work through a list of indices as anticipated, but instead, for ''each'' value of the first index, ''all'' the values of the second index were selected. Thus, instead of the first change being DOT(WHACK('''1''').I,WHACK('''1''').J) only, it was DOT(WHACK('''1''').I,WHACK('''1:WHACKCOUNT''').J) that were being cleared. Accordingly, the fancy syntax has to be abandoned in favour of a specific DO-loop.
 
<syntaxhighlight lang=Fortran"fortran"> MODULE ZhangSuenThinning !Image manipulation.
CONTAINS
SUBROUTINE ZST(DOT) !Attempts to thin out thick lines.
Line 1,919:
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' version 08-10-2016
' compile with: fbc -s console
 
Line 2,079:
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
Line 2,283:
 
=={{header|Groovy}}==
<syntaxhighlight lang="groovy">def zhangSuen(text) {
def image = text.split('\n').collect { line -> line.collect { it == '#' ? 1 : 0} }
def p2, p3, p4, p5, p6, p7, p8, p9
Line 2,309:
}</syntaxhighlight>
Testing:
<syntaxhighlight lang="groovy">def small = """\
................................
.#########.......########.......
Line 2,412:
 
=={{header|Haskell}}==
<syntaxhighlight lang=Haskell"haskell">import Data.Array
import qualified Data.List as List
 
Line 2,564:
=={{header|J}}==
'''Solution:'''
<syntaxhighlight lang="j">isBlackPx=: '1'&=;._2 NB. boolean array of black pixels
toImage=: [: , LF ,.~ '01' {~ ] NB. convert to original representation
frameImg=: 0 ,. 0 , >:@$ {. ] NB. adds border of 0's to image
Line 2,590:
zhangSuen=: [: toImage [: step2@step1^:_ isBlackPx</syntaxhighlight>
'''Alternative, explicit representation of last verb above'''
<syntaxhighlight lang="j">zhangSuenX=: verb define
img=. isBlackPx y
whilst. 0 < +/ , msk1 +.&-. msk2 do.
Line 2,601:
)</syntaxhighlight>
'''Example Use:'''
<syntaxhighlight lang="j">toASCII=: ' #' {~ '1'&=;._2 NB. convert to ASCII representation
 
ExampleImg=: noun define
Line 2,630:
=={{header|Java}}==
{{works with|Java|7}}
<syntaxhighlight lang="java">import java.awt.Point;
import java.util.*;
 
Line 2,768:
=={{header|JavaScript}}==
{{trans|Java}}
<syntaxhighlight lang="javascript">function Point(x, y) {
this.x = x;
this.y = y;
Line 2,894:
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
const pixelstring =
"00000000000000000000000000000000" *
Line 2,989:
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.1.2
 
class Point(val x: Int, val y: Int)
Line 3,111:
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function zhangSuenThin(img)
local dirs={
{ 0,-1},
Line 3,270:
Mathematica supports directly the Thinning methods "Morphological" and "MedialAxis".
The Zhang-Suen algorithm implementation could be done with:
<syntaxhighlight lang=Mathematica"mathematica">nB[mat_] := Delete[mat // Flatten, 5] // Total;
 
nA[mat_] := Module[{l},
Line 3,451:
 
=={{header|Nim}}==
<syntaxhighlight lang=Nim"nim">import math, sequtils, strutils
 
type
Line 3,574:
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">use List::Util qw(sum min);
 
$source = <<'END';
Line 3,658:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}};</span>
Line 3,741:
 
=={{header|PL/I}}==
<syntaxhighlight lang=PL"pl/Ii">zhang: procedure options (main); /* 8 July 2014 */
 
declare pic(10) bit(32) initial (
Line 3,954:
=={{header|Python}}==
Several input images are converted.
<syntaxhighlight lang="python"># -*- coding: utf-8 -*-
 
# Example from [http://nayefreza.wordpress.com/2013/05/11/zhang-suen-thinning-algorithm-java-implementation/ this blog post].
Line 4,101:
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">#lang racket
(define (img-01string->vector str)
(define lines (regexp-split "\n" str))
Line 4,244:
(formerly Perl 6)
Source image may be based on any characters whose low bits are 0 or 1 (which conveniently includes . and #).
<syntaxhighlight lang=perl6"raku" line>my $source = qq:to/EOD/;
................................
.#########.......########.......
Line 4,314:
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program thins a NxM character grid using the Zhang-Suen thinning algorithm.*/
parse arg iFID .; if iFID=='' then iFID='ZHANG_SUEN.DAT'
white=' '; @.=white /* [↓] read the input character grid. */
Line 4,428:
First I define a function zs which given a point and its eight neighbours returns 1 if the point may be culled, 0 otherwise. g indicates if this is step 1 or step 2 in the task description. zs may be changed to remember the step independently if the reader does not wish to explore the algorithm.
 
<syntaxhighlight lang="ruby">class ZhangSuen
NEIGHBOUR8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] # 8 neighbors
CIRCULARS = NEIGHBOUR8 + [NEIGHBOUR8.first] # P2, ... P9, P2
Line 4,513:
=={{header|Sidef}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">class ZhangSuen(str, black="1") {
const NEIGHBOURS = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] # 8 neighbors
const CIRCULARS = (NEIGHBOURS + [NEIGHBOURS.first]) # P2, ... P9, P2
Line 4,587:
{{trans|Python}}
 
<syntaxhighlight lang="swift">import UIKit
 
// testing examples
Line 4,862:
=={{header|Tcl}}==
Only the single image is converted.
<syntaxhighlight lang="tcl"># -*- coding: utf-8 -*-
 
set data {
Line 4,957:
=={{header|VBA}}==
{{trans|Phix}}
<syntaxhighlight lang="vb">Public n As Variant
Private Sub init()
n = [{-1,0;-1,1;0,1;1,1;1,0;1,-1;0,-1;-1,-1;-1,0}]
Line 5,053:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascript">class Point {
construct new(x, y) {
_x = x
10,327

edits