Convert images to computer generated art using delaunay triangulation.

Overview

Triangle logo

Build Status GoDoc license release homebrew

▲ Triangle is a tool for generating triangulated image using delaunay triangulation. It takes a source image and converts it to an abstract image composed of tiles of triangles.

Sample image

The process

  • First the image is blured out to smothen sharp pixel edges. The more blured an image is the more diffused the generated output will be.
  • Second the resulted image is converted to grayscale mode.
  • Then a sobel filter operator is applied on the grayscaled image to obtain the image edges. An optional threshold value is applied to filter out the representative pixels of the resulted image.
  • Lastly the delaunay algorithm is applied on the pixels obtained from the previous step.
blur = tri.Stackblur(img, uint32(width), uint32(height), uint32(*blurRadius))
gray = tri.Grayscale(blur)
sobel = tri.SobelFilter(gray, float64(*sobelThreshold))
points = tri.GetEdgePoints(sobel, *pointsThreshold, *maxPoints)

triangles = delaunay.Init(width, height).Insert(points).GetTriangles()

Features

  • Can process recursively whole directories and subdirectories concurrently.
  • Supports various image types.
  • There is no need to specify the file type, the CLI tool can recognize automatically the input and output file type.
  • Can accept image URL as parameter for the -in flag.
  • Possibility to save the generated image as an SVG file.
  • The generated SVG file can be accessed from the Web browser directly.
  • Clean and intuitive API. The API not only that accepts image files but can also work with image data. This means that the Draw method can be invoked even on data streams. Check this demo for reference.
  • Support for pipe commands (possibility to pipe in and pipe out the source and destination image).

Head over to this subtopic to get a better understanding of the supported features.

Installation and usage

$ go get -u -f github.com/esimov/triangle/cmd/triangle
$ go install

You can also download the binary file from the releases folder.

MacOS (Brew) install

The library can be installed via Homebrew too.

$ brew install triangle

Supported commands

$ triangle --help

The following flags are supported:

Flag Default Description
in n/a Source image
out n/a Destination image
blur 4 Blur radius
pts 2500 Maximum number of points
noise 0 Noise factor
th 20 Points threshold
sobel 10 Sobel filter threshold
solid false Use solid stroke color (yes/no)
wf 0 Wireframe mode (0: without stroke, 1: with stroke, 2: stroke only)
stroke 1 Stroke width
gray false Output in grayscale mode
web false Open the SVG file in the web browser
bg ' ' Background color (specified as hex value)
c system spec. Number of files to process concurrently (workers)

Key features

Process multiple images from a directory concurrently

The CLI tool also let you process multiple images from a directory concurrently. You only need to provide the source and the destination folder by using the -in and -out flags.

$ triangle -in <input_folder> -out <output-folder>

Pipe commands

The CLI tool accepts also pipe commands, which means you can use stdin and stdout without providing a value for the -in and -out flag directly since these defaults to -. For this reason is possible to use curl for example to get an image from the net and invoke the triangulation process over it directly without the need to download the image first and call ▲ Triangle afterwards.

Here are some examples using pipe names:

$ curl <image_url> | triangle > out.jpg
$ cat input/source.jpg | triangle > out.jpg
$ triangle -in input/source.jpg > out.jpg
$ cat input/source.jpg | triangle -out out.jpg
$ triangle -out out.jpg < input/source.jpg

Background color

You can specify a background color in case of transparent background images (.png) by using the -bg flag. This flag accepts a hexadecimal string value. For example setting the flag to -bg=#ffffff00 will set the alpha channel of the resulted image transparent.

Output as image or SVG

By default the output is saved to an image file, but you can export the resulted vertices even to an SVG file. The CLI tool can recognize the output type directly from the file extension. This is a handy addition for those who wish to generate large images without guality loss.

$ triangle -in samples/input.jpg -out output.svg

Using with -web flag you can access the generated svg file directly on the web browser.

$ triangle -in samples/input.jpg -out output.svg -web=true

Supported output types

The following output file types are supported: .jpg, .jpeg, .png, .bmp, .svg.

Tweaks

Setting a lower points threshold, the resulted image will be more like a cubic painting. You can even add a noise factor, generating a more artistic, grainy image.

Here are some examples you can experiment with:

$ triangle -in samples/input.jpg -out output.png -wf=0 -pts=3500 -stroke=2 -blur=2
$ triangle -in samples/input.jpg -out output.png -wf=2 -pts=5500 -stroke=1 -blur=10

Examples

Sample_0 Sample_1 Sample_11 Sample_8

License

Copyright © 2018 Endre Simo

This project is under the MIT License. See the LICENSE file for the full license text.

Issues
  • Overlapping/excessive triangles

    Overlapping/excessive triangles

    So, whenever I try to triangulate an image, there is a problem with some random triangles that are drawn above the necessary ones. Sometimes they are a something like a line, and sometimes they are gigantic. I tried to change value of all of the parameters/flags but no luck. In the attached files is the source and generated images with flags: -pts 5000 -blur 1.

    173 173 img31 img31

    opened by evilfunnybird 15
  • doesn't seem to work

    doesn't seem to work

    	file, err := os.Open("face.jpg")
    	if err != nil {
    		log.Fatalf("Error opening the file: %v", err)
    	}
    	defer file.Close()
    
    	// File to write to
    	nf, err := os.Create("trig.jpeg")
    	if err != nil {
    		log.Fatalf("Error writing the file: %s", err)
    	}
    
    	// Run Triangle algorithm
    	p := &triangle.Processor{
    		// Initialize struct variables
    	}
    	img := &triangle.Image{*p}
    	_, _,_, err = img.Draw(file, nf, func() {})
    	if err != nil {
    		log.Fatalf("Error creating triangles: %s", err)
    	}
    

    I keep getting error: Error creating triangles: image: unknown format

    opened by pjebs 13
  • Parameter details

    Parameter details

    It would be good know in more detail what these parameters do:

    type Processor struct {
    	BlurRadius     
    	SobelThreshold
    	PointsThreshold
    	MaxPoints
    	Wireframe     
    	Noise          
    	StrokeWidth     
    	IsStrokeSolid   
    	Grayscale     
    	OutputToSVG     
    	ShowInBrowser 
    	BgColor      
    }
    

    I'm trying to adjust the MaxPoints based on the area of the detected face: https://github.com/rocketlaunchr/facemask so that the face's beauty is still apparent without giving away the person's identity.

    It would be good if MaxPoints was 0 and BlurRadius was provided, that the algorithm blurs but does not perform the triangulation process.

    opened by pjebs 7
  • SVG output

    SVG output

    First of all thanks for this awesome library!

    Is there a reason I am getting the following message while .svg is included in the readme?

    File type not supported: .svg
    
    opened by elrumordelaluz 5
  • Panic for image with specific dimension

    Panic for image with specific dimension

    Version: 1.0.3 When a 1px height (e.g. 1x1, 10x1, 100x1) image is given as an input, triangle fails to run. (FYI a 1px width (e.g. 1x10, 1x100) image is successfully processed)

    % triangle -in test.jpg -out out.jpg
    Generating triangulated image... -panic: runtime error: index out of range
    
    goroutine 1 [running]:
    github.com/esimov/triangle.StackBlur(0xc0000aa6c0, 0xc000000004, 0xc0000aa6c0)
    	/private/tmp/triangle-20190310-60366-glg0jh/triangle-1.0.3/src/github.com/esimov/triangle/stackblur.go:259 +0xf29
    github.com/esimov/triangle.(*Image).Draw(0xc0000ddbe8, 0x140d280, 0xc0000b4070, 0x140d280, 0xc000010010, 0x1431be0, 0x0, 0x1, 0x1c08400, 0x20300000000000, ...)
    	/private/tmp/triangle-20190310-60366-glg0jh/triangle-1.0.3/src/github.com/esimov/triangle/process.go:102 +0x3ad
    main.main()
    	/private/tmp/triangle-20190310-60366-glg0jh/triangle-1.0.3/src/github.com/esimov/triangle/cmd/triangle/main.go:178 +0xd98
    

    Failing to process such an image is fine, but is it possible to give a more informative message (like "the input is too small")?

    opened by equal-l2 4
  • "Help" sometimes skip descriptions

    In 1.3.0 --help option randomly skips descriptions Screenshots made in Windows Terminal app (from Microsoft Store) with Windows Powershell command line image image image

    opened by evilfunnybird 3
  • can't load package: package

    can't load package: package

    issue installation:

    go install can't load package: package .: no Go files in /home/roboto

    go install triangle

    can't load package: package triangle: cannot find package "triangle" in any of:
            /usr/lib/go/src/triangle (from $GOROOT)
            /home/roboto/go/src/triangle (from $GOPATH)
    

    go env

    GOARCH="amd64"
    GOBIN="/home/roboto/go/bin"
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/roboto/go"
    GORACE=""
    GOROOT="/usr/lib/go"
    GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    CC="gcc"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build567200773=/tmp/go-build -gno-record-gcc-switches"
    CXX="g++"
    CGO_ENABLED="1"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    
    opened by roboto-cloud 3
  • doc: update `brew install`

    doc: update `brew install`

    The formula was introduced in Homebrew/homebrew-core#37749 and it is pretty well maintained in the homebrew/core. Thus updating the doc to use the core version. :)

    opened by chenrui333 2
  • Make a code review and fix errors

    Make a code review and fix errors

    • Use gofmt in all files
    • Remove GOMAXPROCS as it's equal to NumCPU by default
    • Fixed dir value. Issue happens when dir is not in the current folder
    • Added context message to log.Fatal
    • Combines process call in one place
    • Move process to process.go, so it can be reused
    • Remove channel, because process uses mutex
    • Move fmt funcs out of Process func
    • Simplify triangles loop
    opened by plutov 1
  • Export useful fields and functions

    Export useful fields and functions

    This PR simply replaces this package's Point type with the stdlib equivalent (which is structurally identical) and exports a useful image format conversion helper. Both of these changes make it easier to build custom image processing pipelines atop this package.

    opened by whereswaldon 0
  • Minor performance improvements

    Minor performance improvements

    Hello! Thanks so much for this amazing library. It's been really fun to play with over the last day or so.

    This PR is a series of tweaks I made to boost performance. These were guided by pprof and the included benchmark, but only tested on a single x86_64 Linux machine. They may not be an improvement everywhere.

    That being said, they appear to represent a 24% speedup on my test hardware without compromising the output in any way.

    I have never worked with these algorithms before, and it is definitely possible that my work contains mistakes that compromise the algorithms under some edge case that I failed to consider or did not understand.

    I also don't know enough about the algorithms to know if the parameters being benchmarked represent the normal use-case well enough. Perhaps the benchmark should be using different values?

    I did all of this because I have a toy program that transforms my webcam output using this library, and I'm trying to boost the realtime processing capability of this library. Even with all of these enhancements applied, I can only get 15-20FPS for very low-res images.

    Regardless, I hope these are a useful reference point for optimization, even if they ultimately aren't merged.

    opened by whereswaldon 0
  • Apple Silicon Support?

    Apple Silicon Support?

    I have a project which uses glumpy and am trying to get it running natively on my new MacBook. Is there any plan to compile this package for ARM?

    Python 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:05:16) 
    [Clang 12.0.1 ] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import triangle
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/patrickbryant/miniforge3/envs/py38/lib/python3.8/site-packages/triangle/__init__.py", line 13, in <module>
        from .tri import (
      File "/Users/patrickbryant/miniforge3/envs/py38/lib/python3.8/site-packages/triangle/tri.py", line 1, in <module>
        from .core import triang
    ImportError: dlopen(/Users/patrickbryant/miniforge3/envs/py38/lib/python3.8/site-packages/triangle/core.cpython-38-darwin.so, 0x0002): tried: '/core.cpython-38-darwin.so' (no such file), '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib//core.cpython-38-darwin.so' (no such file), '/Users/patrickbryant/miniforge3/envs/py38/lib/python3.8/site-packages/triangle/core.cpython-38-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))
    
    opened by patrickbryant 1
  • goreleaser github action

    goreleaser github action

    I saw your build script and I replaced it (via copy and paste from my other projects so there could be oversight sorry.) With a go-releaser version. It uses a build on tag strategy.

    The output looks like this: https://github.com/arran4/triangle/releases/tag/v2.0.2

    opened by arran4 7
Releases(v2.0.0)
Owner
Endre Simo
Programmer, crafting things and ideas mostly around graphics, image processing, computer vision and machine learning.
Endre Simo
A cross-platform tool to convert images into ascii art and print them on the console

A cross-platform tool to convert images into ascii art and print them on the console

Zoraiz Hassan 897 Jul 31, 2022
Generate high-quality triangulated art from images.

An iterative algorithm to generate high quality triangulated images.

null 53 May 26, 2021
Small project to convert images to grayscale

This is a small http server that will read images from a provided path, convert the image to gray, and then serve back the converted image Usage You c

Wolfgang E Sanyer 0 Nov 5, 2021
Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket

Features Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket Environment Variables IMAGE_SIZES - formax 200x20

null 1 Feb 2, 2022
Go package for computer vision using OpenCV 4 and beyond.

GoCV The GoCV package provides Go language bindings for the OpenCV 4 computer vision library. The GoCV package supports the latest releases of Go and

The Hybrid Group 4.9k Jul 29, 2022
Human-friendly Go module that builds and prints directory trees using ASCII art

Human-friendly Go module that builds and prints directory trees using ASCII art.

Vadym Borodin 4 May 23, 2022
3D line art engine.

ln The 3D Line Art Engine ln is a vector-based 3D renderer written in Go. It is used to produce 2D vector graphics (think SVGs) depicting 3D scenes. T

Michael Fogleman 3.1k Jul 30, 2022
generativeart is a Go package to generate many kinds of generative art.

generativeart is a Go package to generate many kinds of generative art. The goal is to collect some excellent generative art (implemented in R or Processing), and rewrite them in Go again

null 772 Jul 27, 2022
Ascii-art-web

ASCII-ART-WEB Author: Alika96 How to run Run the following commands: For building an image: docker image build -t ascii-art-web-docker . For showing i

null 0 Dec 13, 2021
API for generate image to ASCII Art

ASCII API Generate ASCII art from image. You can try this API here: ascii.projec

Sh4yn 5 Jul 1, 2022
A simple javascript website that takes user input, queries a Go based backend which then creates ascii art and sends it back to the frontend

A simple javascript website that takes user input, queries a Go based backend which then creates ascii art and sends it back to the frontend. Finally the site displays the ascii art and offers the option to download as multiple file types.

null 0 Jan 7, 2022
A command to output longified ascii art.

longify A command to output longified ascii art. Inspired by Tweet from @sheepla: https://twitter.com/Sheeeeepla/status/1522199846870196225 Installati

syumai 9 Jun 20, 2022
Go bindings for OpenGL (generated via glow)

gl This repository holds Go bindings to various OpenGL versions. They are auto-generated using Glow. Features: Go functions that mirror the C specific

OpenGL with Golang 915 Jul 29, 2022
Cryptseaside generates seaside images using Unix nanoseconds as the seed value.

Cryptseaside Welcome to the Cryptseaside project. Cryptseaside generates seaside images using Unix nanoseconds as the seed value.

Rhymof 1 Nov 12, 2021
:foggy: Convert image to ASCII

?? Image2ascii Image2ASCII is a library that converts images into ASCII images and provides command-line tools for easy use. Installation go get githu

秦世成 678 Jul 30, 2022
package for convert DataURLs to image

convert base64 DataURLs to image

Muhammad Al Farizzi 1 Oct 18, 2021
Read and write Netpbm images from Go programs

netpbm Introduction netpbm is a package for the Go programming language that implements image decoders and encoders for the Netpbm image formats. The

Scott Pakin 16 Jul 1, 2022
Pure Golang Library that allows simple LSB steganography on images

Steganography Lib Steganography is a library written in Pure go to allow simple LSB steganography on images. It is capable of both encoding and decodi

Rafael Passos 150 Jul 26, 2022
Resize images and animated GIFs in Go

Lilliput relies on mature, high-performance C libraries to do most of the work of decompressing, resizing and compressing images. It aims to do as little memory allocation as possible and especially not to create garbage in Go. As a result, it is suitable for very high throughput image resizing services.

Discord 1.8k Jul 31, 2022