Sie können das 4-Farben-Problem auch mithilfe von [Kombinationsoptimierung] lösen (http://qiita.com/Tsutomu-KKE@github/items/bfbf4c185ed7004b5721). Hier lesen wir das Problem automatisch aus dem Bild. Das Problem kam von Nikori-sama.
Es gibt mehrere Bereiche und angrenzende Bereiche sind in verschiedenen Farben gestrichen.
$ \ mbox {Variablen} $ td> | $ v_ {ij} \ in \ {0, 1 \} ~ \ für alle i, j $ td> | Bereich i Ist die Farbe j? (1) td> tr> |
$ \ mbox {vorbehaltlich} $ td> | $ \ sum_j {v_ {ij}} = 1 ~ \ forall i $ td> | Wählen Sie eine Farbe ( 2) td> tr> |
td> | Benachbarte Bereiche sollten unterschiedliche Farben haben (3) td> tr> |
Laden Sie die Bilddatei.
python
import networkx as nx
from urllib import request
from PIL import Image, ImageDraw
from collections import Counter
from itertools import product
from random import seed, shuffle
from pulp import *
#Bilddateien lesen
with request.urlopen('https://dl.dropboxusercontent.com/u/35689878/tmp/4c.png') as fd:
im = Image.open(fd)
python
#Repräsentative Farbe(Am häufigsten verwendete Farben)Extrakt
cc = sorted([(v, k) for k, v in Counter(im.getdata()).items()])[-1][1]
# RGB=(0,1,?)Beseitigen Sie die Farbe von
for y, x in product(range(im.height), range(im.width)):
R, G, B = im.getpixel((x, y))[:3]
if (R, G) == (0, 1):
im.putpixel(0, 0, B)
#RGB repräsentativer Farbbereich=(0,1,Ordnungsnummer)Füllen mit
n = 0
for y, x in product(range(im.height), range(im.width)):
if im.getpixel((x, y)) != cc:
continue
ImageDraw.floodfill(im, (x, y), (0, 1, n))
n += 1
#Erweitern Sie die Grenze ein wenig
seed(1)
dd = [(-1, 0), (0, -1), (0, 1), (1, 0)]
for h in range(1):
l = list(product(range(1, im.height-1), range(1, im.width-1)))
shuffle(l)
for y, x in l:
c = im.getpixel((x, y))
if c[:2] == (0, 1):
for i, j in dd:
if im.getpixel((x+i, y+j))[:2] != (0, 1):
im.putpixel((x+i, y+j), c)
Erstellen Sie ein Diagramm mit Bereichen als Punkten und Pixeln zwischen benachbarten Bereichen als Kanten.
python
#Zeigen Sie grafisch, ob sie nebeneinander liegen
g = nx.Graph()
for y, x in product(range(im.height-1), range(im.width-1)):
c1 = im.getpixel((x, y))
if c1[:2] != (0, 1):
continue
c2 = im.getpixel((x+1, y))
c3 = im.getpixel((x, y+1))
if c2[:2] == (0, 1) and c1[2] != c2[2]:
g.add_edge(c1[2], c2[2])
if c3[:2] == (0, 1) and c1[2] != c3[2]:
g.add_edge(c1[2], c3[2])
Formulieren und lösen.
python
#Lösen Sie das 4-Farben-Problem
r4 = range(4)
m = LpProblem() #Mathematisches Modell
#Ob Bereich i Farbe j gemacht werden soll(1)
v = [[LpVariable('v%d_%d'%(i, j), cat=LpBinary) for j in r4] for i in g.nodes()]
for i in g.nodes():
m += lpSum(v[i]) == 1 # (2)
for i, j in g.edges():
for k in r4:
m += v[i][k] + v[j][k] <= 1 # (3)
m.solve()
co = [(97, 132, 219), (228, 128, 109), (255, 241, 164), (121, 201, 164)] #4 Farben
rr = [int(value(lpDot(r4, i))) for i in v] #Ergebnis
for y, x in product(range(im.height-1), range(im.width-1)):
c = im.getpixel((x, y))
if c[:2] == (0, 1): #Wenn es sich um einen Bereich handelt, malen Sie mit dem Ergebnis
ImageDraw.floodfill(im, (x, y), co[rr[c[2]]])
im.save('result.png')
Als ich es tatsächlich versuchte, war es in Ordnung.
das ist alles
Recommended Posts