class MLE: def __init__(self, image, **kwargs): self.connectivity = kwargs.pop("connectivity", "8") self.filename = image self.image = Image(filename=self.filename) self.folder = kwargs.pop("folder", "chain") self.guz, self.theta0 = self.loadChain() self.gux = self.countChars() self.theta = numpy.copy(self.theta0) self.allThetas = {1: list(self.theta)} def iteration(self): num_u = numpy.array([0, 0, 0]) den_u = 0 for i in range(len(self.guz)): num_u = num_u + self.guz[i]*numpy.exp(sum(self.guz[i]*self.theta - self.guz[i]*self.theta0)) den_u = den_u + numpy.exp(sum(self.guz[i]*self.theta - self.guz[i]*self.theta0)) u = self.gux - num_u/den_u num_j = 0 den_j = 0 for i in range(len(self.guz)): num_j = num_j + sum((self.guz[i] - num_u/den_u)**2)*numpy.exp(sum(self.guz[i]*self.theta - self.guz[i]*self.theta0)) den_j = den_j + numpy.exp(sum(self.guz[i]*self.theta - self.guz[i]*self.theta0)) j = num_j/den_j self.theta = self.theta + u/j self.allThetas[list(self.allThetas.keys())[-1]+1] = list(self.theta) def loadChain(self): with open(os.path.join(*self.folder.split(os.sep), "characteristics.json"), "r") as chars: chain = json.loads(chars.read()) guz = list() for i in range(len(chain.keys())-5): chars = chain[str(i+1)] guz.append(numpy.array([chars[0], chars[1], chars[2][0]-chars[2][1]])) return guz, numpy.array(chain["params"]) def saveThetas(self): path = self.filename.split(os.sep)[:-1] + ["estimation.json"] with open(os.sep.join(path), "w") as thetaFile: thetaFile.write(json.dumps(self.allThetas, sort_keys=True, indent=4)) def countChars(self): a = self.image.area() l = self.image.length() chi = self.image.chi(self.connectivity) return numpy.array([a, l, chi[0]-chi[1]])
class MH: def __init__(self, **kwargs): self.connectivity = kwargs.pop("connectivity", 8) self.size = kwargs.pop("size", 100) self.iters = kwargs.pop("iters", 1000) self.r = kwargs.pop("r", (5, 10)) self.intensity = kwargs.pop("intensity", 1) self.params = numpy.array(list(kwargs.pop("params", (0, 0, 0)))) self.image = Image(matrix=numpy.ones((self.size, self.size), dtype=numpy.uint8)*255) self.circles = list() def iteration(self): action = "add" if random.random() < 0.5 or len(self.circles) == 0 else "remove" if action == "add": circle = self.drawCircle() if random.random() < self.HR(action): self.circles.append(circle) self.commit() else: index = self.removeCircle() if random.random() > self.HR(action): del self.circles[index] self.commit() return self.image.matrix, [self.image.area(), self.image.length(), self.image.chi(self.connectivity)] def makeImage(self, circles): image = Image(matrix=numpy.ones((self.size, self.size), dtype=numpy.uint8)*255) for circle in circles: cv2.circle(image.matrix, *circle, 0, -1) return image def drawCircle(self): self.temp = Image(matrix=numpy.copy(self.image.matrix)) circle = self.randomCircle() cv2.circle(self.temp.matrix, *circle, 0, -1) return circle def removeCircle(self): index = random.randrange(len(self.circles)) self.temp = self.makeImage(self.circles[:index] + self.circles[index+1:]) return index def randomCircle(self): r = random.randrange(*self.r) circle = ((random.randrange(r + 1, self.size - r), random.randrange(r + 1, self.size - r)), r) return circle def chars(self): chi = self.image.chi(self.connectivity) chars = [self.image.area(), self.image.length(), chi[0] - chi[1]] return numpy.array(chars) def tempChars(self): chi = self.temp.chi(self.connectivity) chars = [self.temp.area(), self.temp.length(), chi[0] - chi[1]] return numpy.array(chars) def H(self, G, n): ratio = self.intensity*numpy.exp(numpy.sum(self.params*G))/(n + 1) return ratio def HR(self, action): if action == "add": G = self.tempChars() - self.chars() ratio = self.H(G, len(self.circles)) else: G = self.chars() - self.tempChars() ratio = 1/self.H(G, len(self.circles) - 1) return min(ratio, 1) def commit(self): self.image.matrix = numpy.copy(self.temp.matrix)