Пример #1
0
class DirectCVCamSource(BasePlugin):

    configParameter = [
        ImageType('outputImageName', output=True),
        IntType('camId'),
        IntType('frameWidth'),
        IntType('frameHeight'),
    ]

    def __init__(self, **kwargs):
        super(DirectCVCamSource, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def preCyclicCall(self):
        self.initCam()

    def initCam(self):
        self.cam = cv2.VideoCapture(self.camId.value)

        if self.frameWidth > 0:
            self.cam.set(cv2.CAP_PROP_FRAME_WIDTH, self.frameWidth.value)
        if self.frameHeight > 0:
            self.cam.set(cv2.CAP_PROP_FRAME_HEIGHT, self.frameHeight.value)

    def timeBypassActions(self):
        self.cam.grab()

    def externalCall(self):
        self.cam.grab()
        i, image = self.cam.read()
        self.outputImageName.data = image.copy()
Пример #2
0
class CVDrawContours(BasePlugin):
    """
    if inputContourIndexListName is empty, then draw all contours
    """

    configParameter = [
        NameType('inputImageName', input=True),
        NameType('outputImageName', output=True),
        NameType('inputContourName', input=True),
        IntType('thickness'),
        NameType('inputContourIndexListName', input=True),
        IntListType('contourColor'),
    ]

    def __init__(self, **kwargs):
        super(CVDrawContours, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def externalCall(self):
        if self.inputContourIndexListName.data:
            contidx = self.inputContourIndexListName.data
        else:
            contidx = range(len(self.inputContourName.data))

        imagecpy = self.inputImageName.data.copy()
        for cidx in contidx:
            cv2.drawContours(imagecpy,
                             self.inputContourName.data,
                             cidx,
                             color=self.contourColor,
                             thickness=self.thickness.value)
        self.outputImageName.data = imagecpy
Пример #3
0
class Threshold(BasePlugin):

    configParameter = [
        ImageType('inputImage', input=True),
        ImageType('outputImage', output=True),
        IntType('threshold'),
        IntType('max'),
        IntType('type'),
    ]

    def __init__(self, **kwargs):
        super(Threshold, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def externalCall(self):
        image = self.inputImage.data
        ret, image = cv2.threshold(image, self.threshold.value, self.max.value,
                                   self.type.value)
        self.outputImage.data = image
Пример #4
0
class Canny(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        NameType('outputImageName', output=True),
        IntType('threshold1', input=True),
        IntType('threshold2', input=True),
    ]

    def __init__(self, **kwargs):
        super(Canny, self).__init__(**kwargs)

    def externalCall(self):
        image = self.inputImageName.data
        image = cv2.GaussianBlur(image, (3, 3), 1)
        #image = cv2.Laplacian(image,cv2.CV_64F, delta=self.threshold1.value, scale=2)
        image = cv2.Canny(image,
                          self.threshold1.value,
                          self.threshold2.value,
                          L2gradient=False)  #, apertureSize=3)
        self.outputImageName.data = image
Пример #5
0
class DeltaTimePerFrame(BasePlugin):

    configParameter = [
        BoolType('displayTime'),
        IntType('startFrame'),
        IntType('stopFrame'),
    ]

    def __init__(self, **kwargs):
        super(DeltaTimePerFrame, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def preCyclicCall(self):
        self.lastCallTime = time.time()
        self.timeList = list()
        self.frameCount = 1

    def externalCall(self):
        curtime = time.time()
        difftime = curtime - self.lastCallTime
        self.lastCallTime = curtime

        if self.startFrame.value <= self.frameCount <= self.stopFrame.value:
            self.timeList.append(difftime)

            if self.displayTime.value:
                print 'Frame: <%d>' % self.frameCount,
                self.printTime(difftime)
        self.frameCount += 1

        if self.frameCount == self.stopFrame:
            self.postCyclicCall()

    def postCyclicCall(self):
        midtime = float(sum(self.timeList)) / len(self.timeList)
        self.printTime(midtime)

    def printTime(self, time):
        print '%.2f' % (time * 1.e3), 'ms', 1 / time, 'Hz'
Пример #6
0
class CVGaussBlur(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        NameType('outputImageName', output=True),
        FloatType('sigmaX'), FloatType('sigmaY'),
        IntType('kSize', constraint=range(1,99,2)),
    ]

    def __init__(self, **kwargs):
        super(CVGaussBlur, self).__init__(**kwargs)

    def externalCall(self):
        image = self.inputImageName.data
        image = cv2.GaussianBlur(image, (self.kSize.value, self.kSize.value),
                                 sigmaX=self.sigmaX.value, sigmaY=self.sigmaY.value)
        self.outputImageName.data = image
Пример #7
0
class PyrDown(BasePlugin):

    configParameter = [
        ImageType('inputImage', input=True),
        ImageType('outputImage', output=True),
        IntType('times'),
    ]

    def __init__(self, **kwargs):
        super(PyrDown, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def externalCall(self):
        image = self.inputImage.data
        for i in range(self.times.value):
            image = cv2.pyrDown(image)
        self.outputImage.data = image
Пример #8
0
class DirectKinectSource(BasePlugin):

    configParameter = [
        IntType('camId'),
        ImageType('outputImageName', output=True),
        ImageType('outputDepthImageName', output=True),
        NameType('outputDepthRawName', output=True),
        BoolType('reverseDepthVisualisation'),
    ]

    def __init__(self, **kwargs):
        super(DirectKinectSource, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def externalCall(self):
        #try:
        self.log.debug('try to get image from cam')
        imageData, _ = freenect.sync_get_video(index=self.camId.value)
        depthDataRaw, _ = freenect.sync_get_depth()
        #except TypeError:
        #    self.log.error('asd')

        imageData = np.array(imageData)
        imageData = cv2.cvtColor(imageData, cv2.COLOR_RGB2BGR)

        self.outputImageName.data = imageData.copy()

        depthDataImage = np.float32(depthDataRaw)

        #depthDataImage = (depthDataImage)/2047*256
        #depthDataImage = np.uint8(depthDataImage)
        #depthDataImage = np.float32(depthDataImage) * 255 / 130
        depthDataImage = np.uint8(depthDataImage)

        #depthDataImage = depthDataImage * 255 / 130

        #depthDataImage = np.uint8(cv2.normalize(depthDataImage, depthDataImage, 0, 255, cv2.NORM_MINMAX))

        if self.reverseDepthVisualisation.value:
            depthDataImage = 255 - depthDataImage

        self.outputDepthImageName.data = depthDataImage.copy()
        self.outputDepthRawName.data = depthDataRaw.copy()
Пример #9
0
class WaitKey(BasePlugin):

    configParameter = [
        IntType('waitTime'),
        StringListType('keyList'),
        StringListType('functionList'),
    ]

    def __init__(self, **kwargs):
        super(WaitKey, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')
        self.cm = ContextManager()

    def preCyclicCall(self):
        self.pm = self.cm.processManager

    def timeBypassActions(self):
        self.checkKey()

    def externalCall(self):
        self.checkKey()

    def checkKey(self):
        key = (cv2.waitKey(self.waitTime.value) & 255)
        chkey = chr(key)
        if chkey in self.keyList:
            for k, v in enumerate(self.keyList.value):
                if chkey is v:
                    fnc = getattr(self, self.functionList[k])
                    fnc()

    def stateHold(self):
        self.pm.changeState(self.pm.STATE_HOLD)
        print 'HOLD'

    def stateQuit(self):
        self.pm.changeState(self.pm.STATE_QUIT)
        print 'QUIT'

    def stateRun(self):
        self.pm.changeState(self.pm.STATE_RUN)
        print 'RUN'
Пример #10
0
class WeightChanels(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        ImageType('outputImageName', output=True),
        IntType('ofs'),
    ]

    def __init__(self, **kwargs):
        super(WeightChanels, self).__init__(**kwargs)

    def preCyclicCall(self):
        pass

    def externalCall(self):

        hlut = np.sin(np.linspace(0, np.pi, 31))
        hblk = np.zeros(180 - hlut.size, np.float32)
        hlut = np.concatenate((hlut, hblk))
        self.hlut = np.roll(hlut, self.ofs.value)

        flut = np.sin(np.linspace(0, np.pi * 0.5, 256)) * 255
        fblk = np.zeros(256 - flut.size, np.float32)
        self.flut = np.concatenate((flut, fblk))

        tflut = np.sin(np.linspace(0, np.pi * 0.8, 256)) * 255
        tfblk = np.zeros(256 - tflut.size, np.float32)
        self.tflut = np.concatenate((tflut, tfblk))

        image = self.inputImageName.data


        image = np.array(self.hlut[image[:, :, 0]] * \
            (0.2 * self.tflut[image[:, :, 1]] +
             0.8 * self.flut[image[:, :, 2]]), np.uint8)

        self.outputImageName.data = image
Пример #11
0
class CVDrawCicles(BasePlugin):
    """
    if inputContourIndexListName is empty, then draw all contours
    """

    configParameter = [
        ImageType('inputImageName', input=True),
        StringType('circleData', input=True),
        ImageType('outputImageName', output=True),
        BoolType('binarizedOutput'),
        IntListType('color'),
        IntType('thickness'),
    ]

    def __init__(self, **kwargs):
        super(CVDrawCicles, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

    def externalCall(self):

        if self.binarizedOutput.value:
            if len(self.inputImageName.data.shape) > 1:
                image = np.zeros(tuple(self.inputImageName.data.shape[:2]),
                                 np.uint8)
            else:
                image = np.zeros_like(self.inputImageName.data)
        else:
            image = self.inputImageName.data.copy()

        if self.circleData.data is not None:
            for circ in self.circleData.data[0]:
                cv2.circle(image, (circ[0], circ[1]), circ[2],
                           self.color.value, self.thickness.value)

        self.outputImageName.data = image
class FilePickleSegmentOutput(BasePlugin):

    configParameter = [
        NameType('inputImageName', input=True),
        NameType('inputContourName', input=True),
        NameType('inputContourIndexListName', input=True),
        StringType('outputFile'),
        BoolType('overwriteExistingFile'),
        BoolType('createFilePath'),
        IntType('cacheCycles'),
        BoolType('skipDump'),
    ]

    def __init__(self, **kwargs):
        super(FilePickleSegmentOutput, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')
        self.timelist = list()

    def preCyclicCall(self):
        self.log.debug('preCyclicCall called')
        self.pickleCycleCntr = 0
        self.pickleCache = list()
        self.log.debug('open dataFile at <%s> in mode "write binary"',
                       self.outputFile.value)
        self.dataFile = open(self.outputFile.value, 'wb')

    def externalCall(self):

        self.log.debug('externalCall called')
        self.appendOutputDataToCache()

        if self.cacheCycles.value is not -1 and self.pickleCycleCntr >= self.cacheCycles.value:
            self.writeCacheToFile()
            self.pickleCycleCntr = -1
        self.pickleCycleCntr += 1

        if len(self.timelist) > 0:
            print sum(self.timelist) / float(len(self.timelist))

    def postCyclicCall(self):
        self.log.debug('postCyclicCall called')
        self.writeCacheToFile()
        self.dataFile.close()

    def appendOutputDataToCache(self):
        image = self.inputImageName.data
        cont = self.inputContourName.data

        if len(self.inputContourIndexListName.data) > 0:
            contidx = self.inputContourIndexListName.data
        else:
            contidx = range(len(cont))

        #create

        #ToDo: Now there is a new Plugin called 'CreateContourBinaryImage'. Use it!

        shape = list(image.shape[0:2])
        #shape = list(image.shape)
        shape.insert(0, len(contidx))
        shape = tuple(shape)

        ccimage = np.zeros(shape, np.uint8)

        for k, v in enumerate(contidx):
            cv2.drawContours(ccimage[k], cont, v, (255, 255, 255), -1)

        singleImageDump = list()

        #each found segment in image
        for segmentid, segmentcnt in enumerate(ccimage):

            pixlist = np.nonzero(segmentcnt)
            singleImageDump.append([cont[contidx[segmentid]], pixlist])
            print[cont[contidx[segmentid]], pixlist]

        #if len(singleImageDump) > 0:
        self.pickleCache.append(image)
        self.pickleCache.append(singleImageDump)

    def writeCacheToFile(self):
        self.log.debug('check if skipDump <%s>', self.skipDump.value)
        if self.skipDump.value:
            self.log.debug('writeCacheToFile method is skipped')
            return

        #ToDo: create directory if not exist and allowed

        cnt = 2
        cntmax = len(self.pickleCache)
        objectDumpNames = ['raw-image', 'segments']
        self.log.debug('dump %d frames to file <%s>', cntmax,
                       self.outputFile.value)
        for data in self.pickleCache:
            stime = time.time()
            self.log.debug('Frame %d of %d (%s)', cnt / 2, cntmax / 2,
                           objectDumpNames[cnt % 2])
            pickle.dump(data, self.dataFile, -1)
            self.log.debug('Time to save file: %f3',
                           (time.time() - stime) * 1000)
            cnt += 1
        print
        self.pickleCache = list()
Пример #13
0
class MSER(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        ImageType('inputOrginalImageName', input=True),
        ImageType('outputImageName', output=True),
        ImageType('outputImageMask', output=True),
        ImageType('outputOrginalImageFilt', output=True),
        FloatType('maskScale'),
        IntType('minRadius'),
        IntType('maxRadius'),
    ]

    def __init__(self, **kwargs):
        super(MSER, self).__init__(**kwargs)


    def preCyclicCall(self):
        pass

    def externalCall(self):
        d_red = cv2.cv.RGB(200, 100, 100)
        l_red = cv2.cv.RGB(250, 200, 200)
        d_green = cv2.cv.RGB(100, 200, 100)
        l_green = cv2.cv.RGB(200, 250, 200)

        orig = self.inputOrginalImageName.data
        img = orig.copy()
        #img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img2 = self.inputImageName.data

        detector = cv2.FeatureDetector_create('MSER')
        fs = detector.detect(img2)
        #print dir(detector)

        fs.sort(key=lambda x: -x.size)


        def supress(x):
                for f in fs:
                    distx = f.pt[0] - x.pt[0]
                    disty = f.pt[1] - x.pt[1]
                    dist = math.sqrt(distx*distx + disty*disty)
                    #print f.size/1.5
                    if (f.size > x.size) and (dist < f.size/2) \
                        :#or (f.size > self.maxRadius.value) or (f.size < self.minRadius.value):
                        #print dist, self.minRadius.value, self.maxRadius.value

                        return True

        sfs = [x for x in fs if not supress(x)]

        mask = np.zeros_like(img2)

        for f in sfs:
                cv2.circle(img, (int(f.pt[0]), int(f.pt[1])), int(2), d_red, 1)
                cv2.circle(img, (int(f.pt[0]), int(f.pt[1])), int(f.size/2), d_green, 1)
                cv2.circle(mask, (int(f.pt[0]), int(f.pt[1])), int(f.size/1.5*self.maskScale.value), 255, -1)

        h, w = orig.shape[:2]
        #vis = np.zeros((h, w*2+5), np.uint8)
        #vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
        #vis[:h, :w] = orig
        #vis[:h, w+5:w*2+5] = img

        filt = np.zeros_like(orig)

        cv2.merge((mask, mask, mask), filt)

        filt = cv2.bitwise_and(orig, filt)

        self.outputImageMask.data = mask
        self.outputImageName.data = img
        self.outputOrginalImageFilt.data = filt
class SideCamCircleDetector(BasePlugin):

    configParameter = [
        NameType('inputImageName', input=True),
        NameType('outputImageName', output=True),
        NameType('inputContourName', input=True),
        IntType('thickness'),
        NameType('inputContourIndexListName', input=True),
        BoolType('detected', output=True),
    ]

    def __init__(self, **kwargs):
        super(SideCamCircleDetector, self).__init__(**kwargs)


    def preCyclicCall(self):
        pass

    def externalCall(self):

        self.detected.data = False
        if self.inputContourIndexListName.data:
            contidx = self.inputContourIndexListName.data
        else:
            contidx = range(len(self.inputContourName.data))
        image = self.inputImageName.data.copy()

        for cidx in contidx:
            cnt = self.inputContourName.data[cidx]
            mask = np.zeros(tuple(self.inputImageName.data.shape[:2]), np.uint8)
            cv2.drawContours(mask, self.inputContourName.data, -1, color=(250,250,50), thickness=-1)

            moments = cv2.moments(cnt)
            humoments = cv2.HuMoments(moments)

            try:
                centroid_x = moments['m10']/moments['m00']
                centroid_y = moments['m01']/moments['m00']
            except ZeroDivisionError:
                continue

            area = moments['m00']

            equi_diameter = np.sqrt(4*area/np.pi) * 1.05
            equi_radian = equi_diameter / 2.0







            minhu = 1.59e-1
            maxhu = 1.65e-1 # normal 1.64e-1
            overhu = 1.70e-1

            minarea = 2500
            maxarea = 6000


            quality = (humoments[0] - minhu) / (maxhu - minhu)


            color = (50, 250, 50)
            state = 'green'
            if humoments[0] > (maxhu) or humoments[0] < (minhu) or area < minarea or area > maxarea:
                color = (50, 50, 250)
                #continue
                state = 'red'


            self.detected.data = True


            if state == 'red':
                #continue
                pass






            #cv2.drawContours(image, self.inputContourName.data, -1, color=(250,250,50), thickness=1)

            #print '+++', state, gcorr, xm, 'sqrt ' + str(gcorr**2 - xm**2), '->', ym


            #self.scatter[int(ym*100)][int(xm*100)+100] += 0.14
            #cv2.imshow('scatter', cv2.pyrUp(self.scatter))
            #cv2.imwrite('data/scatterx.jpg', self.scatter)


            #self.drawText(image, '%.2f'%xm, int(xopt), int(centroid_y), scale=1, color=(225, 225, 225))
            #self.drawText(image, '%.2f'%ym, int(centroid_x), image.shape[0]-10, scale=1, color=(225, 225, 225))


            #cv2.line(image, (int(centroid_x), int(centroid_y)), (int(xopt), int(centroid_y)), (200,50,50), 1)
            #cv2.line(image, (int(centroid_x), int(centroid_y)), (int(centroid_x), image.shape[0]), (50,150,250), 1)

            #cv2.circle(image, (int(centroid_x), int(centroid_y)), int(equi_radian), (250, 250, 100), 1)
            #cv2.circle(image, (int(centroid_x), int(centroid_y)), 3, color=(255,50,50), thickness=-1)

            if True:
                #image[int(centroid_y-70-equi_radian):int(centroid_y-equi_radian-10), centroid_x-40:centroid_x+80] *= 0.45
                #self.drawTextMarker(image, 'X: ' + str(round(centroid_x, 2)), centroid_x, centroid_y, equi_radian, 0, color)
                #self.drawTextMarker(image, 'Y: ' + str(round(centroid_y, 2)), centroid_x, centroid_y, equi_radian, 1, color)
                #self.drawTextMarker(image, 'Radian: ' + str(round(equi_radian, 2)), centroid_x, centroid_y, equi_radian, 1, color)
                self.drawTextMarker(image, 'HM0' + ': %.2e' % humoments[0], centroid_x, centroid_y, equi_radian, 2, color)
                self.drawTextMarker(image, 'Area' + ': %.2f' % area + 'm', centroid_x, centroid_y, equi_radian, 3, color)
                self.drawTextMarker(image, '' + ': %.2f' % (quality * 100) + '%', centroid_x, centroid_y, equi_radian, 4, color)


        cv2.imshow('xxx', image)

        crop = cv2.pyrUp(image)

        #crop = image[100:650, 550:1100]
        #crop = cv2.pyrUp(crop)

        cv2.imshow('crop', crop)


    def drawTextMarker(self, image, text, xpos, ypos, radian, line, color=(225, 225, 225)):
        xofs = -35
        ystep = 15
        yofs = int(radian) + ystep * 5
        yofs *= -1

        self.drawText(image, text, int(xpos) + xofs, int(ypos) + yofs + ystep * line, 0.8, color)

    def drawText(self, image, text, xpos, ypos, scale=1, color=(225, 225, 225)):
        for i in range(3, 0, -1):
            if i < 2:
                cv2.putText(image, text, (xpos+i, ypos+i),
                            cv2.FONT_HERSHEY_PLAIN, scale, color)
            else:
                cv2.putText(image, text, (xpos+i, ypos+i),
                            cv2.FONT_HERSHEY_PLAIN, scale, (50, 50, 50))
Пример #15
0
class Calibrate(BasePlugin):

    configParameter = [
        ImageType('inputImage', input=True),
        ImageType('outputImage', output=True),
        IntType('visualTresholdLow'),
        IntType('gridX'),
        IntType('gridY'),
        IntType('dataPerGridCell'),
        IntType('successHue'),
        IntType('boardw'),
        IntType('boardh'),
        FloatType('delay'),
        StringType('outputFileName'),
        BoolType('syncCalculation'),
    ]

    def __init__(self, **kwargs):
        super(Calibrate, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

        self.data = np.zeros((self.gridY.value, self.gridX.value), np.uint8)

        self.board_w = self.boardw.value
        self.board_h = self.boardh.value

        self.board_n = self.board_w * self.board_h
        self.board_sz = (self.board_w, self.board_h)  # size of board

        pattern_size = (self.board_w, self.board_h)
        self.pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32)
        self.pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
        #pattern_points *= cbsq

        self.obj_points = list()
        self.img_points = list()

        self.last_time = time.time()

        self.syncObj = None

        self.calculationDone = False
        self.calculationVisualisation = False

    def externalCall(self):

        waitForSync = False
        if self.syncCalculation.value:

            waitForSync = True

            if not self.syncObj:
                self.syncObj = StringType('syncSection')
                self.syncObj.value = self.sectionConfig['syncSection']
                self.syncObj.data = False
                self.sectionConfig['syncSection'] = self.syncObj

            syncObjOther = self.fullConfig[self.syncObj.value][
                self.syncObj.name]
            if isinstance(syncObjOther, StringType):
                waitForSync = not syncObjOther.data

            #print self.logicSectionName,

            #print self.logicSectionName, self.fullConfig[secObj.value]['foo']

        image = self.inputImage.data

        # PREPARE VISUALIZATION

        if self.data is None:
            self.data = np.zeros((self.gridY.value, self.gridX.value),
                                 np.uint8)

        hsv = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2HSV)

        hsv[..., 0] = 0
        hsv[..., 1] = 255

        dark = hsv[..., 2] < self.visualTresholdLow.value
        hsv[dark] = self.visualTresholdLow.value

        # DRAW VISUALIZATION

        totalx = image.shape[1]
        totaly = image.shape[0]
        xsize = totalx // self.gridX.value
        ysize = totaly // self.gridY.value

        for y, yline in enumerate(self.data):
            for x, value in enumerate(yline):
                hsv[ysize * y:ysize * (y + 1), xsize * x:xsize * (x + 1),
                    0] = value * int(
                        self.successHue.value / self.dataPerGridCell.value)

        doCalculate = self.data.sum() >= (self.dataPerGridCell.value *
                                          self.data.size)

        # AQUIRE BOARD DATA
        isBoard = False
        waitForDelay = time.time() - self.last_time <= self.delay.value
        if not doCalculate and not waitForDelay:

            isBoard, boardData = cv2.findChessboardCorners(
                image, self.board_sz, self.board_n,
                cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FILTER_QUADS)

            attachToList = False

            if isBoard:
                cv2.drawChessboardCorners(hsv, self.board_sz, boardData, 0)
                for point in boardData:
                    x, y = point[0]
                    if self.data[y //
                                 ysize][x //
                                        xsize] < self.dataPerGridCell.value:
                        self.data[y // ysize][x // xsize] += 1
                        attachToList = True
                    self.last_time = time.time()

            if attachToList:
                self.img_points.append(boardData.reshape(-1, 2))
                self.obj_points.append(self.pattern_points)

        # CALCULATE
        self.syncObj.data = doCalculate
        if doCalculate and not waitForSync and not self.calculationDone and self.calculationVisualisation:

            self.calculationDone = True

            rms, camera_matrix, dist_coefs, rvecs, tvecs = cv2.calibrateCamera(
                self.obj_points, self.img_points, (totalx, totaly))

            print '*' * 100
            print self.logicSectionName
            print '*' * 100
            print "RMS:", rms
            print "camera matrix:\n", camera_matrix
            print "distortion coefficients: ", dist_coefs.ravel()
            print '*' * 100

            with open(self.outputFileName.value, 'wb') as f:
                pickle.dump(camera_matrix, f, -1)
                pickle.dump(dist_coefs, f, -1)
                pickle.dump(rms, f, -1)
                pickle.dump(rvecs, f, -1)
                pickle.dump(tvecs, f, -1)

        self.outputImage.data = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

        if doCalculate:
            if waitForSync:
                textStr = 'wait for sync'
            else:
                if not self.calculationDone:
                    textStr = 'calculating'
                    self.calculationVisualisation = True
                else:
                    textStr = 'done'
        else:
            if isBoard or waitForDelay:
                textStr = 'board found'
            else:
                textStr = 'searching board'

        drawText(self.outputImage.data,
                 textStr,
                 50,
                 50,
                 scale=2,
                 thickness=3,
                 bgthickness=3)
Пример #16
0
class Histogram(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        ImageType('outputImageName', output=True),
        IntType('scale'),
    ]

    def __init__(self, **kwargs):
        super(Histogram, self).__init__(**kwargs)
        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

        self.hsv_map = np.zeros((180, 256, 3), np.uint8)
        h, s = np.indices(self.hsv_map.shape[:2])
        self.hsv_map[:, :, 0] = h
        self.hsv_map[:, :, 1] = s
        self.hsv_map[:, :, 2] = 255
        self.hsv_map = cv2.cvtColor(self.hsv_map, cv2.COLOR_HSV2BGR)

    def externalCall(self):

        image = self.inputImageName.data
        image = cv2.pyrDown(image)

        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        h = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

        h = np.clip(h * 0.005 * self.scale.value, 0, 1)
        vis = self.hsv_map * h[:, :, np.newaxis] / 255.0

        vis = cv2.pyrUp(vis)

        colsub = (0.2, 0.6, 0.2)
        colmain = (0.3, 0.9, 0.3)

        blacksize = 5

        for i in range(10, 360, 10):
            cv2.line(vis, (0, i), (5, i), 0, blacksize)
            cv2.line(vis, (0, i), (5, i), colsub, 1)
        for i in range(30, 360, 30):
            cv2.line(vis, (0, i), (15, i), 0, blacksize)
            cv2.line(vis, (0, i), (15, i), colmain, 1)

        for i in range(20, 510, 20):
            cv2.line(vis, (i, 0), (i, 5), 0, blacksize)
            cv2.line(vis, (i, 0), (i, 5), colsub, 1)
        for i in range(100, 510, 100):
            cv2.line(vis, (i, 0), (i, 15), 0, blacksize)
            cv2.line(vis, (i, 0), (i, 15), colmain, 1)

        nvis = np.zeros((vis.shape[0] + 15, vis.shape[1] + 30, vis.shape[2]))
        nvis[15:, 30:, ...] = vis

        nvis[15:, 30, ...] = colsub
        self.drawText(nvis, 'SATURATION', 450, 10, 0.6, colsub)  # 32
        self.drawText(nvis, 'HUE', 4, 367, 0.6, colsub)

        for i in range(50, 300, 50):
            self.drawText(nvis, str(i), i * 2 + 17, 10, 0.75, colmain)

        for i in range(15, 180, 15):
            self.drawText(nvis, str(i), 0, i * 2 + 18, 0.75, colmain)

        #nvis = cv2.pyrUp(nvis)
        self.outputImageName.data = nvis

    def drawText(self,
                 image,
                 text,
                 xpos,
                 ypos,
                 scale=1,
                 color=(225, 225, 225)):
        xpos = int(xpos)
        ypos = int(ypos)
        for i in range(1, 0, -1):
            if i < 2:
                cv2.putText(image, text, (xpos + i, ypos + i),
                            cv2.FONT_HERSHEY_PLAIN, scale, color)
            else:
                cv2.putText(image, text, (xpos + i, ypos + i),
                            cv2.FONT_HERSHEY_PLAIN, scale, (50, 50, 50))
Пример #17
0
class HoughCircles(BasePlugin):

    configParameter = [
        ImageType('inputImageName', input=True),
        StringType('circleData', output=True),
        IntType('dp', constraint=range(1, 1000)),
        IntType('minDist', constraint=range(1, 1000)),
        IntType('minRad', constraint=range(1, 1000)),
        IntType('maxRad', constraint=range(1, 1000)),
        IntType('threshold1', constraint=range(1, 1000)),
        IntType('threshold2', constraint=range(1, 1000)),
        ImageType('inputOrgImageName', input=True),
        BoolType('doDrawCircles'),
        ImageType('outputOrgCircleImageName', output=True),
        BoolType('doCannyOutput'),
        ImageType('outputCannyImageName', output=True),
    ]

    def __init__(self, **kwargs):
        super(HoughCircles, self).__init__(**kwargs)

    def externalCall(self):

        reslist = cv2.HoughCircles(self.inputImageName.data,
                                   cv2.cv.CV_HOUGH_GRADIENT,
                                   dp=self.dp.value,
                                   minDist=self.minDist.value,
                                   minRadius=self.minRad.value,
                                   maxRadius=self.maxRad.value,
                                   param1=self.threshold1.value,
                                   param2=self.threshold2.value)

        self.circleData.data = reslist

        if self.doCannyOutput.value:
            image = self.inputImageName.data
            canny = cv2.Canny(image, self.threshold1.value,
                              self.threshold1.value // 2)
            self.outputCannyImageName.data = canny

        if self.doDrawCircles.value:
            resvisimage = self.inputOrgImageName.data.copy()

            if reslist is not None and len(reslist):
                for x in reslist[0]:
                    corr = 5
                    mask = np.zeros(tuple(self.inputImageName.data.shape[:2]),
                                    np.uint8)
                    cv2.circle(mask, (x[0], x[1]), int(x[2] - corr), 255, -1)

                    mean_val = cv2.mean(self.inputOrgImageName.data, mask=mask)
                    mv = np.zeros((1, 1, 3), np.uint8)

                    mv[..., 0] = mean_val[0]
                    mv[..., 1] = mean_val[1]
                    mv[..., 2] = mean_val[2]

                    mv2 = cv2.cvtColor(mv, cv2.COLOR_BGR2HSV)

                    #cv2.circle(resvisimage, (x[0], x[1]), int(x[2]-corr), (mean_val[0],mean_val[1],mean_val[2]), -1)
                    self.drawText(resvisimage, str(mv2[0, 0]), x[0] - 40,
                                  x[1] - self.maxRad.value - 4, 1)

                    if 28 > mv2[0, 0, 0] or mv2[0, 0, 0] > 32 or mv2[
                            0, 0, 1] < 70 or mv2[0, 0, 2] < 150:
                        #continue
                        pass

                    cv2.circle(resvisimage, (x[0], x[1]), self.minRad.value,
                               (100, 255, 100), 1)
                    cv2.circle(resvisimage, (x[0], x[1]), self.maxRad.value,
                               (100, 100, 255), 1)
                    cv2.circle(resvisimage, (x[0], x[1]), self.minDist.value,
                               (100, 100, 100), 1)
                    cv2.circle(resvisimage, (x[0], x[1]), x[2],
                               (255, 100, 100), 2)
                    cv2.circle(resvisimage, (x[0], x[1]), 4, (50, 50, 50), -1)

            self.outputOrgCircleImageName.data = resvisimage

    def drawText(self,
                 image,
                 text,
                 xpos,
                 ypos,
                 scale=1,
                 color=(225, 225, 225)):
        xpos = int(xpos)
        ypos = int(ypos)
        for i in range(3, 0, -1):
            if i < 2:
                cv2.putText(image, text, (xpos + i, ypos + i),
                            cv2.FONT_HERSHEY_PLAIN, scale, color)
            else:
                cv2.putText(image, text, (xpos + i, ypos + i),
                            cv2.FONT_HERSHEY_PLAIN, scale, (50, 50, 50))
Пример #18
0
class CircleDetector(BasePlugin):

    configParameter = [
        NameType('inputImageName', input=True),
        NameType('outputImageName', output=True),
        NameType('inputContourName', input=True),
        IntType('thickness'),
        NameType('inputContourIndexListName', input=True),
        NameType('inputCalibrationData', input=True),
    ]

    def __init__(self, **kwargs):
        super(CircleDetector, self).__init__(**kwargs)


    def preCyclicCall(self):
        pass

    def externalCall(self):
        if self.inputContourIndexListName.data:
            contidx = self.inputContourIndexListName.data
        else:
            contidx = range(len(self.inputContourName.data))
        image = self.inputImageName.data.copy()

        for cidx in contidx:
            cnt = self.inputContourName.data[cidx]
            mask = np.zeros(tuple(self.inputImageName.data.shape[:2]), np.uint8)
            cv2.drawContours(mask, self.inputContourName.data, -1, color=(250,250,50), thickness=-1)

            moments = cv2.moments(cnt)
            humoments = cv2.HuMoments(moments)


            try:
                centroid_x = moments['m10']/moments['m00']
                centroid_y = moments['m01']/moments['m00']
            except ZeroDivisionError:
                continue

            area = moments['m00']

            equi_diameter = np.sqrt(4*area/np.pi) * 1.05
            equi_radian = equi_diameter / 2.0



            #print self.inputCalibrationData.data
            xopt = self.inputCalibrationData.data[0, 2]
            yopt = self.inputCalibrationData.data[1, 2]



            # OPTICAL CENTER CROSSHAIR
            ##########################

            if showCalib:
                cv2.circle(image, (int(xopt), int(yopt)), 2, (100, 250, 100), -1)
                cv2.circle(image, (int(xopt), int(yopt)), 1, (250, 100, 100), -1)
                image[int(yopt), ..., 0:2] *= 0.5
                image[int(yopt), ...] *= 255.0 / image[int(yopt), ...].max()
                image[...,int(xopt), 0:2] *= 0.5
                image[...,int(xopt), 2] *= 255.0 / image[..., int(xopt), ...].max()

            mpp = 3.0677e-6
            B = equi_diameter * mpp
            G = 0.0429
            b = 4.02e-3
            g = b/B*G
            gcorr = g + G/2

            color = (50, 250, 50)


            minhu = 1.59e-1
            maxhu = 1.65e-1 # normal 1.64e-1
            overhu = 1.70e-1


            quality = (humoments[0] - minhu) / (maxhu - minhu)


            state = 'green'
            if humoments[0] > (maxhu) or humoments[0] < (minhu) or equi_radian < 13 or equi_radian > 45:
                color = (50, 50, 250)
                #equi_diameter *= quality
                #equi_radian = equi_diameter / 2.0
                if showCalib:
                    continue
                #continue
                state = 'red'

            if humoments[0] < (overhu) and humoments[0] > (maxhu):
                color = (50, 150, 250)
                state = 'orange'

            if equi_radian < 13 or equi_radian > 45:
                color = (250, 150, 150)

            if state == 'red':
                #continue
                pass


            #cv2.drawContours(image, self.inputContourName.data, -1, color=(250,250,50), thickness=1)

            xpx = centroid_x - xopt
            xm = 0.0429 / equi_diameter * xpx

            ym = np.sqrt(gcorr**2 - np.abs(xm**2))
            #print '+++', state, gcorr, xm, 'sqrt ' + str(gcorr**2 - xm**2), '->', ym


            #self.scatter[int(ym*100)][int(xm*100)+100] += 0.14
            #cv2.imshow('scatter', cv2.pyrUp(self.scatter))
            #cv2.imwrite('data/scatterx.jpg', self.scatter)

            if showCalib:
                self.drawText(image, '%.2f'%xm, int(xopt), int(centroid_y), scale=1, color=(225, 225, 225))
                self.drawText(image, '%.2f'%ym, int(centroid_x), image.shape[0]-10, scale=1, color=(225, 225, 225))


                cv2.line(image, (int(centroid_x), int(centroid_y)), (int(xopt), int(centroid_y)), (200,50,50), 1)
                cv2.line(image, (int(centroid_x), int(centroid_y)), (int(centroid_x), image.shape[0]), (50,150,250), 1)

            cv2.circle(image, (int(centroid_x), int(centroid_y)), int(equi_radian), (250, 250, 100), 1)
            cv2.circle(image, (int(centroid_x), int(centroid_y)), 3, color=(255,50,50), thickness=-1)

            if True:
                image[int(centroid_y-70-equi_radian):int(centroid_y-equi_radian-10), centroid_x-40:centroid_x+80] *= 0.45
                #self.drawTextMarker(image, 'X: ' + str(round(centroid_x, 2)), centroid_x, centroid_y, equi_radian, 0, color)
                #self.drawTextMarker(image, 'Y: ' + str(round(centroid_y, 2)), centroid_x, centroid_y, equi_radian, 1, color)
                self.drawTextMarker(image, 'Radian: ' + str(round(equi_radian, 2)), centroid_x, centroid_y, equi_radian, 1, color)
                self.drawTextMarker(image, 'HM0' + ': %.2e' % humoments[0], centroid_x, centroid_y, equi_radian, 2, color)
                self.drawTextMarker(image, 'Distance' + ': %.2f' % gcorr + 'm', centroid_x, centroid_y, equi_radian, 3, color)
                self.drawTextMarker(image, 'Diff' + ': %.2f' % (quality * 100) + '%', centroid_x, centroid_y, equi_radian, 4, color)


        cv2.imshow('xxx', image)
        cv2.imwrite('data/bdvdoku/20_imagecd_false_positive.jpg', image)


        crop = image[50:375, 325:850]
        crop = cv2.pyrUp(crop)
        cv2.imshow('crop', crop)


    def drawTextMarker(self, image, text, xpos, ypos, radian, line, color=(225, 225, 225)):
        xofs = -35
        ystep = 15
        yofs = int(radian) + ystep * 5
        yofs *= -1

        self.drawText(image, text, int(xpos) + xofs, int(ypos) + yofs + ystep * line, 0.8, color)

    def drawText(self, image, text, xpos, ypos, scale=1, color=(225, 225, 225)):
        for i in range(3, 0, -1):
            if i < 2:
                cv2.putText(image, text, (xpos+i, ypos+i),
                            cv2.FONT_HERSHEY_PLAIN, scale, color)
            else:
                cv2.putText(image, text, (xpos+i, ypos+i),
                            cv2.FONT_HERSHEY_PLAIN, scale, (50, 50, 50))
Пример #19
0
class ProcessManager(object):
    """Manages the Process and is responsibly for the runtime behavior"""

    logicSectionName = 'GENERAL'

    configParameter = [
        StringListType('pluginSequence'),
        StringType('exitKey'),
        IntType('leadTime'),
        BoolType('waitLeadTime'),
        BoolType('runOnce'),
    ]

    def __init__(self, pluginController, configController):
        """Gets the 'GENERAL' section from the ConfigController and acquires and
        instantiate the Plugins specified by the 'pluginSequence' Option in the
        Configuration

        :param pluginController: Instance of the ``PluginController``
        :param configController: Instance of the ``ConfigController``
        :param dataLinkController: Instance of the ``DataLinkController``
        """

        # Logging
        ##########

        self.log = logging.getLogger(__name__)
        self.log.debug('logging started')

        # ProcessStuff
        ###############

        assert isinstance(pluginController, PluginController)
        self.pluginController = pluginController

        assert isinstance(configController, ConfigController)
        self.configController = configController
        # Init-Specific (Config / Plugins)
        ###################################

        fullConfig = self.configController.getConfig()
        self.sectionConfig = self.configController.getSection(self.logicSectionName)
        bp = BasePlugin(sectionConfig=self.sectionConfig,
                        logicSectionName=self.logicSectionName,
                        fullConfig=fullConfig)
        bp.loadOptions(self)

        self.pluginDtoList = self.acquirePlugins()
        self.instantiatePlugins()

        # Cycle-Specific (execute Plugins / handle runtime characteristics)
        ####################################################################

        curTime = time.time()
        self.lastExecTime = curTime
        self.lastBypassTime = curTime
        self.lastCycleTime = curTime

        self.deltaExecTime = 0
        self.deltaBypassTime = 0

    def acquirePlugins(self):
        """Acquire the Plugins specified by the 'pluginSequence' Option in the
        Configuration given by the dict generalConfigSection or internal config if
        generalConfigSection is None.
        Furthermore returns a list of PluginDto for each loaded Plugin whose Name in
        the pluginSequence Option don't start with an exclamation mark

        :param generalConfigSection: Config for 'GENERAL' section (default ``None``)
        """

        self.log.debug('enter acquirePlugins')
        pluginDtoList = list()
        for section in self.pluginSequence:
            if not section.startswith('!'):
                pdto = PluginDTO()
                pdto.sectionName = section
                self.log.debug('try loading for sectionName <%s>', pdto.sectionName)
                #FIXME: Figure out when it fails!
                try:
                    pdto.modulePath = self.configController.getOption(section,
                                                                      'pluginPath')
                except AssertionError as e:
                    self.log.critical('asd %s', e.message)

                pdto.classObject = self.pluginController.loadPluginClass(
                    pdto.modulePath)
                if pdto.classObject is None:
                    continue
                pluginDtoList.append(pdto)
        return pluginDtoList

    def instantiatePlugins(self, pluginDtoList=None):
        """Instantiate the Plugins in the list of PluginDto's

        :param pluginDtoList: List of PluginDto's (default None)
        """

        self.log.debug('enter instantiatePlugins')
        self.log.debug('check pluginDtoList')
        if pluginDtoList is None:
            self.log.debug('load private data')
            pluginDtoList = self.pluginDtoList
        if pluginDtoList is None:
            return None

        self.log.debug('instantiate Plugins')
        for pdto in pluginDtoList:
            assert isinstance(pdto, PluginDTO)
            self.log.debug('instantiate Plugin <%s> for Section <%s>',
                           pdto.modulePath, pdto.sectionName)

            fullConfig = self.configController.getConfig()
            sectionConfig = self.configController.getSection(pdto.sectionName)
            pdto.instanceObject = pdto.classObject(sectionConfig=sectionConfig,
                                                   logicSectionName=pdto.sectionName,
                                                   fullConfig=fullConfig)


    def executePlugins(self, pluginDtoList=None):
        if pluginDtoList is None:
            pluginDtoList = self.pluginDtoList
        assert isinstance(pluginDtoList, list)


        self.log.debug('')
        self.log.debug('=' * 30 + ' REGISTER DEPENDENCY ' + '=' * 30)
        self.registerDependency()

        self.log.debug('')
        self.log.debug('=' * 30 + ' RUN ACTIVE MODULES ' + '=' * 30)

        self.triggerPluginMethods('preCyclicCall')

        isFirstRun = True
        while True:
            leadTime = self.leadTime.value / 1000.0
            curTime = time.time()
            deltaExec = curTime - self.lastExecTime

            if isFirstRun or (deltaExec + self.deltaBypassTime) > leadTime:
                waitTime = leadTime - deltaExec

                if self.waitLeadTime.value and not isFirstRun and waitTime > 0:
                    time.sleep(waitTime)

                self.lastExecTime = time.time()
                self.triggerPluginMethods('externalCall')
                self.deltaExecTime = time.time() - self.lastExecTime
            else:
                self.lastBypassTime = time.time()
                self.triggerPluginMethods('timeBypassActions')
                self.deltaBypassTime = time.time() - self.lastBypassTime

            isFirstRun = False

            if self.runOnce.value:
                break

            if (cv2.waitKey(10) & 255) == ord(self.exitKey.value):
                break


        self.triggerPluginMethods('postCyclicCall')

    def triggerPluginMethods(self, methodName, pluginDtoList=None):
        """Triggers the corresponding methods of the active Plugins in the
        pluginDtoList

        :param methodName: Name of the Plugin-Method to trigger
        :param pluginDtoList: List of PluginDto's (default None)
        """

        if pluginDtoList is None:
            pluginDtoList = self.pluginDtoList
        assert isinstance(pluginDtoList, list)

        for pdto in pluginDtoList:
            assert isinstance(pdto, PluginDTO)
            pdtoObj = pdto.instanceObject
            if not pdtoObj.activeModule:
                self.log.debug('Skipping inactive Module <%s> for logical Section <%s>',
                               pdtoObj.__class__.__name__, pdtoObj.logicSectionName)
                continue

            self.log.debug('Calling Module <%s> for logical Section <%s>',
                           pdtoObj.__class__.__name__, pdtoObj.logicSectionName)

            moduleFunction = getattr(pdtoObj, methodName)
            moduleFunction()

    def registerDependency(self, pluginDtoList=None):

        if pluginDtoList is None:
            pluginDtoList = self.pluginDtoList
        assert isinstance(pluginDtoList, list)

        inputParameter = dict()
        outputParameter = dict()


        self.log.debug('')
        self.log.debug('-' * 30 + ' PreLoad I/O-Parameter ' + '-' * 30)
        for pdto in pluginDtoList:
            self.log.debug('.' * 20 + ' <%s> ' + '.' * 20,
                           pdto.instanceObject.logicSectionName)
            assert isinstance(pdto, PluginDTO)
            baseTypeParameter = [x for x in pdto.instanceObject.sectionConfig.values()
                                 if issubclass(type(x), BaseType) and
                                    (x.output or x.input)]

            for x in baseTypeParameter:
                if x.input:
                    self.log.debug('input found:')
                    self.attachToDependencyIOList(x, inputParameter)

                if x.output:
                    self.log.debug('output found:')
                    self.attachToDependencyIOList(x, outputParameter)

        self.log.debug('')
        self.log.debug('-' * 30 + ' Wire I/O-Callbacks for Parameter-Types '
                       + '-' * 30)

        for oname, opara in outputParameter.items():
            if oname in inputParameter:
                for output in opara:
                    for ipara in inputParameter[oname]:
                        self.log.debug('parameter <%s> for value <%s> to <%s> on value <%s> ',
                                       output.name, output.value, ipara.value, ipara.name)
                        output.registerDataUpdate(ipara.dataUpdateCallback)


    def attachToDependencyIOList(self, para, dstList):
        valueList = para.value
        if not isinstance(valueList, list):
            valueList = [valueList]

        for value in valueList:
            if value not in dstList:
                dstList[value] = list()

            self.log.debug('parameter <%s> for value <%s>', para.name, value)
            dstList[value].append(para)