Note that there are some explanatory texts on larger screens.

plurals
  1. POstorages in OpenCV with Python
    primarykey
    data
    text
    <p>I want to find contours in an image and further process them e.g. drawing them on the image. To do that I have two functions running in different threads:</p> <pre><code>storage = cv.CreateMemStorage(0) contour = cv.FindContours(inData.content, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) </code></pre> <p>and</p> <pre><code>while contours: bound_rect = cv.BoundingRect(list(contours)) contours = contours.h_next() pt1 = (bound_rect[0], bound_rect[1]) pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) cv.Rectangle(inImg.content, pt1, pt2, cv.CV_RGB(255,0,0), 1) </code></pre> <p>Each function runs in a loop processing one image after the other. When a function is done it puts the image in a buffer from which the other function can get it. This works except that in the result the contours are drawn in the image one or two images before their corresponding image.</p> <p>I think this has something to do with the storage of OpenCV but I don't understand why the storage is needed and what it does</p> <p><strong>EDIT</strong> Here is some more code:<br> My program is meant to be a node based image analasys software.<br> This is how the node graph of my current code looks like: </p> <pre><code> |---------| |--------| |-----| |-----|------&gt;|Threshold|---&gt;|Contours|---&gt;|-------------| |------| |Input|---&gt;|Split| |---------| |--------| |Draw Contours|---&gt;|Output| |-----| |-----|-----------------------------------&gt;|-------------| |------| </code></pre> <hr> <p>This is the class from which all nodes derive:</p> <pre><code>from Buffer import Buffer from threading import Thread from Data import Data class Node(Thread): def __init__(self, inputbuffers, outputbuffers): Thread.__init__(self) self.inputbuffers = inputbuffers self.outputbuffers = outputbuffers def getInputBuffer(self, index): return self.inputbuffers[index] def getOutputBuffer(self, index): return self.outputbuffers[index] def _getContents(self, bufferArray): out = [] for bufferToGet in bufferArray: if bufferToGet and bufferToGet.data: out.append(bufferToGet.data) for bufferToGet in bufferArray: bufferToGet.data = None return out def _allInputsPresent(self): for bufferToChk in self.inputbuffers: if not bufferToChk.data: return False return True def _allOutputsEmpty(self): for bufferToChk in self.outputbuffers: if bufferToChk.data != None: return False return True def _applyOutputs(self, output): for i in range(len(output)): if self.outputbuffers[i]: self.outputbuffers[i].setData(output[i]) def run(self): #Thread loop &lt;------------------------------------ while True: while not self._allInputsPresent(): pass inputs = self._getContents(self.inputbuffers) output = [None]*len(self.outputbuffers) self.process(inputs, output) while not self._allOutputsEmpty(): pass self._applyOutputs(output) def process(self, inputs, outputs): ''' inputs: array of Data objects outputs: array of Data objects ''' pass </code></pre> <hr> <p>The nodes pass around these Data objects:</p> <pre><code>class Data(object): def __init__(self, content = None, time = None, error = None, number = -1): self.content = content #Here the actual data is stored. Mostly images self.time = time #Not used yet self.error = error #Not used yet self.number = number #Used to see if the correct data is put together </code></pre> <hr> <p>This are the nodes:</p> <pre><code>from Node import Node from Data import Data import copy import cv class TemplateNode(Node): def __init__(self, inputbuffers, outputbuffers): super(type(self), self).__init__(inputbuffers, outputbuffers) def process(self, inputs, outputs): inData = inputs[0] #Do something with the content e.g. #cv.Smooth(inData.content, inData.content, cv.CV_GAUSSIAN, 11, 11) outputs[0] = inData class InputNode(Node): def __init__(self, inputbuffers, outputbuffers): super(InputNode, self).__init__(inputbuffers, outputbuffers) self.capture = cv.CaptureFromFile("video.avi") self.counter = 0 def process(self, inputs, outputs): image = cv.QueryFrame(self.capture) if image: font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 1, 1, 0, 3, 8) x = 30 y = 50 cv.PutText(image, str(self.counter), (x,y), font, 255) outputs[0] = Data(image,None,None,self.counter) self.counter = self.counter+1 class OutputNode(Node): def __init__(self, inputbuffers, outputbuffers, name): super(type(self), self).__init__(inputbuffers, outputbuffers) self.name = name def process(self, inputs, outputs): if type(inputs[0].content) == cv.iplimage: cv.ShowImage(self.name, inputs[0].content) cv.WaitKey() class ThresholdNode(Node): def __init__(self, inputbuffers, outputbuffers): super(type(self), self).__init__(inputbuffers, outputbuffers) def process(self, inputs, outputs): inData = inputs[0] inimg = cv.CreateImage(cv.GetSize(inData.content), cv.IPL_DEPTH_8U, 1); cv.CvtColor(inData.content, inimg, cv.CV_BGR2GRAY) outImg = cv.CreateImage(cv.GetSize(inimg), cv.IPL_DEPTH_8U, 1); cv.Threshold(inimg, outImg, 70, 255, cv.CV_THRESH_BINARY_INV); inData.content = outImg outputs[0] = inData class SplitNode(Node): def __init__(self, inputbuffers, outputbuffers): super(type(self), self).__init__(inputbuffers, outputbuffers) def process(self, inputs, outputs): inData = inputs[0] if type(inData.content) == cv.iplimage: imagecpy = cv.CloneImage(inData.content) outputs[1] = Data(imagecpy, copy.copy(inData.time), copy.copy(inData.error), copy.copy(inData.number)) else: outputs[1] = copy.deepcopy(inData) print class ContoursNode(Node): def __init__(self, inputbuffers, outputbuffers): super(type(self), self).__init__(inputbuffers, outputbuffers) def process(self, inputs, outputs): inData = inputs[0] storage = cv.CreateMemStorage(0) contours = cv.FindContours(inData.content, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) contoursArr = [] while contours: points = [] for (x,y) in contours: points.append((x,y)) contoursArr.append(points) contours = contours.h_next() outputs[0] = Data(contoursArr, inData.time, inData.error, inData.number) pass class DrawContoursNode(Node): def __init__(self, inputbuffers, outputbuffers): super(type(self), self).__init__(inputbuffers, outputbuffers) def process(self, inputs, outputs): inImg = inputs[0] contours = inputs[1].content print "Image start" for cont in contours: for (x,y) in cont: cv.Circle(inImg.content, (x,y), 2, cv.CV_RGB(255, 0, 0)) print "Image end" outputs[0] = inImg </code></pre> <hr> <p>This is the main function. Here all the nodes and buffers are created.</p> <pre><code>from NodeImpls import * from Buffer import Buffer buffer1 = Buffer() buffer2 = Buffer() buffer3 = Buffer() buffer4 = Buffer() buffer5 = Buffer() buffer6 = Buffer() innode = InputNode([], [buffer1]) split = SplitNode([buffer1], [buffer2, buffer3]) thresh = ThresholdNode([buffer3], [buffer4]) contours = ContoursNode([buffer4], [buffer5]) drawc = DrawContoursNode([buffer2, buffer5],[buffer6]) outnode = OutputNode([buffer6], [], "out1") innode.start() split.start() thresh.start() contours.start() drawc.start() outnode.start() while True: pass </code></pre> <hr> <p>The buffer:</p> <pre><code>class Buffer(object): def __init__(self): self.data = None def setData(self, data): self.data = data def getData(self): return self.data </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload