Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python在OpenCV中存储_Python_Opencv - Fatal编程技术网

使用Python在OpenCV中存储

使用Python在OpenCV中存储,python,opencv,Python,Opencv,我想在图像中找到轮廓并进一步处理,例如在图像上绘制轮廓。 为此,我在不同的线程中运行了两个函数: storage = cv.CreateMemStorage(0) contour = cv.FindContours(inData.content, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) 及 每个函数在一个循环中运行,依次处理一个图像。 当一个函数完成时,它将图像放入一个缓冲区中,另一个函数可以从中获取图像。 这是可行的,

我想在图像中找到轮廓并进一步处理,例如在图像上绘制轮廓。 为此,我在不同的线程中运行了两个函数:

storage = cv.CreateMemStorage(0)
contour = cv.FindContours(inData.content, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE)

每个函数在一个循环中运行,依次处理一个图像。 当一个函数完成时,它将图像放入一个缓冲区中,另一个函数可以从中获取图像。 这是可行的,除了在结果中,轮廓在图像中绘制一个或两个图像,然后再绘制相应的图像

我认为这与OpenCV的存储有关,但我不明白为什么需要存储以及它的作用

编辑这里还有一些代码:
我的程序是一个基于节点的图像分析软件。
以下是我当前代码的节点图:

                         |---------|    |--------|
|-----|    |-----|------>|Threshold|--->|Contours|--->|-------------|    |------|
|Input|--->|Split|       |---------|    |--------|    |Draw Contours|--->|Output|
|-----|    |-----|----------------------------------->|-------------|    |------|

这是从中派生所有节点的类:

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 <------------------------------------
        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

以下是节点:

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

这是主要功能。这里创建了所有节点和缓冲区

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

缓冲区:

class Buffer(object):

    def __init__(self):
        self.data = None

    def setData(self, data):
        self.data = data
    def getData(self):
        return self.data
我认为这与OpenCV的存储有关,但我不明白为什么需要存储以及它的作用

存储只是一个保存结果的地方。OpenCV是一个C++库,依赖于手动内存分配,C++风格。Python绑定只是围绕它的一个薄薄的包装,并不是非常pythonic的。这就是为什么你必须手动分配存储,就像你在C或C++中那样做的。 我有两个函数在不同的线程中运行 ... 这是可行的,除了在结果中,轮廓在图像中绘制一个或两个图像,然后再绘制相应的图像

我假设您的线程没有正确同步。这个问题可能与OpenCV无关,但与您拥有的函数、它们使用和传递的数据以及如何在它们之间共享数据有关


简而言之,请将您的代码张贴在创建线程和调用这些函数的地方,以及访问或修改
inImg
inData
contour
contours
storage
的地方。

非常感谢您的帮助!我在问题中添加了我的代码。@AntonS在您的源代码中,我看到不同的线程(节点)共享相同的数据(缓冲区),而没有锁。最快的线程继续运行,并用新数据覆盖其输出缓冲区。为了同步每个生产者-消费者对,可以使用条件对象另一个链接:也可以考虑使用<代码> DeQue/代码>队列@安顿,事实上,我怀疑线程在这里有任何优势。数据流中没有并行性或并发性,通过适当的同步,所有线程都将等待最慢的线程(DrawContours?)。实际上,这意味着它们将像在正常的顺序代码中一样按顺序工作,但要组织正确的同步,需要付出更多的努力。像通常的函数一样实现节点,并在其中无限循环。同步问题解决后,您的代码更快(开销更少)且更易于维护。要点:我认为我的程序中存在并行性。没有平行分支是正确的,但例如,阈值节点可以处理图像10,而轮廓节点处理图像9。关于1。要点:我使用“队列”而不是缓冲区。但这没什么区别。我不明白为什么我必须同步线程:由于队列的原因,两个线程不应该尝试使用相同的映像。
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
class Buffer(object):

    def __init__(self):
        self.data = None

    def setData(self, data):
        self.data = data
    def getData(self):
        return self.data