Skip to content

Instantly share code, notes, and snippets.

@seovchinnikov
Created December 10, 2017 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seovchinnikov/3dffbd86a8c1d3c6d8e2096250ba7448 to your computer and use it in GitHub Desktop.
Save seovchinnikov/3dffbd86a8c1d3c6d8e2096250ba7448 to your computer and use it in GitHub Desktop.
import cv2
import pickle
import math
import random
import copy
PKL = 'points.pkl'
IMG_NAME = 'graphen.png'
LINKS = ((0, 1, 2, 3, 4, 5, 6), (1, 7, 8, 9, 10, 2), (8, 11, 12, 13, 14, 9), (12, 15, 16, 17, 18, 19, 13),
(3, 2, 10, 25, 21, 20), (10, 9, 14, 32, 29, 26, 25), (14, 13, 19, 36, 33, 32), (24, 20, 21, 22, 23),
(21, 25, 26, 27, 28, 22), (26, 29, 30, 31, 27), (29, 32, 33, 34, 35, 30), (33, 36, 37, 38, 34),
(42, 23, 22, 28, 39, 40, 41, 42), (28, 27, 31, 43, 44, 39), (31, 30, 35, 45, 46, 43),
(35, 34, 38, 47, 48, 49, 45),)
class Point:
x = -1
y = -1
id = -1
plus = 0
links = None
def __init__(self, id, x=-1, y=-1, links = [], plus=0):
self.x = x
self.y = y
self.id = id
self.links = []
self.links.extend(links)
self.plus = plus
class Config:
points = None
signs = None
betta=1
def __init__(self, points, betta=1., signs=None):
self.points = points
if signs is None:
signs = {}
for point in points:
signs[point.id] = random.choice([1, -1])
self.signs = signs
self.betta = betta
def clone(self):
conf_new = Config(self.points, self.betta)
conf_new.signs = copy.deepcopy(self.signs)
return conf_new
def computeEnergy(self):
summ = 0
i = 0
for point in self.points:
for link in point.links:
if point.id<self.points[link].id:
summ += self.signs[point.id]*self.signs[self.points[link].id]
i+=1
summ= math.exp(summ * self.betta)
print(i)
return summ
# def compute_dif_energy(self, num):
# potential_cand = self.points[num]
# new_conf = self.clone()
# new_conf.signs[num] = - new_conf.signs[num]
# new_energy = new_conf.computeEnergy()
# old_energy = self.computeEnergy()
# diff = new_energy - old_energy
# return (diff, new_conf)
def compute_sum_diff(self, num):
potential_cand = self.points[num]
summ = 0
for link in potential_cand.links:
summ += self.signs[self.points[link].id]
summ*=self.signs[num]
return summ
def try_to_move(self, num):
diff = self.compute_sum_diff(num)
p = min(1, math.exp(-2.*self.betta*diff))
move_success = random.random() < p
if move_success:
new_conf = self.clone()
new_conf.signs[num] = - new_conf.signs[num]
#print 'transition'
return (True, new_conf)
return (False, self)
def pointsMark():
res = []
img = cv2.imread(IMG_NAME)
count = [0]
def drawPoints(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 5, (255, 0, 0), -1)
cv2.putText(img, str(count[0]), (x+5, y+5), cv2.FONT_HERSHEY_SIMPLEX, 1, 255)
print(count[0], x,y)
res.append(Point(count[0], x, y))
count[0] += 1
cv2.namedWindow('image')
cv2.setMouseCallback('image', drawPoints)
while (1):
cv2.imshow('image', img)
k = cv2.waitKey(20) & 0xFF
if k == 27:
break
elif k == ord('a'):
break
cv2.imwrite('points.png', img)
return res
def startAndSafePoints():
res = pointsMark()
with open(PKL, 'wb') as output:
pickle.dump(res, output, pickle.HIGHEST_PROTOCOL)
print(len(res))
def loadPoints():
with open(PKL, 'rb') as input:
points = pickle.load(input)
return points
def fillLinks(points):
links = LINKS
for link_set in links:
for i in range(len(link_set)):
this_el = link_set[(i) % len(link_set)]
neighb = link_set[(i+1) % len(link_set)]
if neighb not in points[this_el].links:
points[this_el].links.append(neighb)
if this_el not in points[neighb].links:
points[neighb].links.append(this_el)
def drawPointsAndLinks(points):
img = cv2.imread(IMG_NAME)
for point in points:
cv2.circle(img, (point.x, point.y), 5, (255, 0, 0), -1)
cv2.putText(img, str(point.id), (point.x + 5, point.y + 5), cv2.FONT_HERSHEY_SIMPLEX, 1, 255)
for link in point.links:
neigb = points[link]
cv2.line(img, (point.x, point.y), (neigb.x, neigb.y), (0, 255, 0), 2)
cv2.imshow('image', img)
cv2.waitKey()
def drawConf(conf):
points = conf.points
img = cv2.imread(IMG_NAME)
for point in points:
for link in point.links:
neigb = points[link]
cv2.line(img, (point.x, point.y), (neigb.x, neigb.y), (122, 122, 122), 2)
cv2.circle(img, (point.x, point.y), 5, (255, 0, 0) if conf.signs[point.id] == -1 else (0, 0, 255), -1)
cv2.putText(img, str(point.id), (point.x + 5, point.y + 5), cv2.FONT_HERSHEY_SIMPLEX, 1, 255)
cv2.imshow('image', img)
cv2.waitKey()
# def resave_points(points):
# for point in points:
# point.links = []
# with open('points_.pkl', 'wb') as output:
# pickle.dump(points, output, pickle.HIGHEST_PROTOCOL)
def start_improve_model(start, max):
cnt = 0
new_model = start
while cnt < max:
new_pos = random.choice(new_model.signs.keys())
succ, new_model = new_model.try_to_move(new_pos)
if succ:
cnt+=1
return new_model
points = loadPoints()
#resave_points(points)
fillLinks(points)
#drawPointsAndLinks(points)
conf = Config(points, betta=0.6)
last = start_improve_model(conf, 10000)
drawConf(last)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment