def __call__(self, context, *args):
     LOG.info(self.mess)
     tsi = args[0]
     self.image = tsi.pixels
     meanIntensity = np.mean(self.image)
     if meanIntensity < self.minIntensity:
         # FIXME: this should be handled with an error.
         LOG.warn('Image is too dark, skiping colorcard detection!')
         return([self.image, [None, None, None]])
     if not self.useWhiteBackground:
         self.imagePyramid = cd.createImagePyramid(self.image)
         ccdImg = cv2.imread(self.ccf)[:, :, ::-1]
         if ccdImg is None:
             raise ValueError("Failed to read %s" % self.ccf)
         self.colorcardPyramid = cd.createImagePyramid(ccdImg)
         # create image pyramid for multiscale matching
         SearchRange = [self.colorcardPyramid[0].shape[1],
                        self.colorcardPyramid[0].shape[0]]
         score, loc, angle = cd.matchTemplatePyramid(
             self.imagePyramid,
             self.colorcardPyramid,
             0,
             EstimatedLocation=self.colorcardPosition,
             SearchRange=SearchRange
         )
         if score > 0.3:
             # extract color information
             self.foundCard = self.image[
                 loc[1] - ccdImg.shape[0] // 2:loc[1] + ccdImg.shape[0] // 2,
                 loc[0] - ccdImg.shape[1] // 2:loc[0] + ccdImg.shape[1] // 2]
             self.ccdColors, _ = cd.getColorcardColors(self.foundCard,
                                                       GridSize=[6, 4])
             self.colorcardParams = cd.estimateColorParameters(
                 self.colorcardTrueColors,
                 self.colorcardColors
             )
             # Save colourcard image to instance
             self.colorcardImage = ccdImg
             # for displaying
             self.loc = loc
         else:
             # FIXME: this should be handled with an error.
             LOG.warn('Cannot find color card')
             self.colorcardParams = [None, None, None]
     else:
         self.colorcardParams = cd.estimateColorParametersFromWhiteBackground(
             self.image, self.backgroundWindow, self.maxIntensity)
     return([tsi, self.colorcardParams])
    def __call__(self, context, *args):
        LOG.info(self.mess)
        tsi = args[0]
        self.image = tsi.pixels
        temp = np.zeros_like(self.image)
        temp[:, :, :] = self.image[:, :, :]
        temp[:, :, 1] = 0  # suppress green channel
        self.imagePyramid = cd.createImagePyramid(temp)
        self.trayPyramids = []
        for i in range(self.trayNumber):
            # fixed tray image so that perspective postions of the trays are
            # fixed
            trayFile = os.path.join(context.ints.path,
                                    self.settingPath,
                                    self.trayFiles % i)
            trayImage = cv2.imread(trayFile)[:, :, ::-1]
            if trayImage is None:
                LOG.error("Fail to read", trayFile)
            trayImage[:, :, 1] = 0  # suppress green channel
            trayPyramid = cd.createImagePyramid(trayImage)
            self.trayPyramids.append(trayPyramid)

        self.trayLocs = []
        for i, trayPyramid in enumerate(self.trayPyramids):
            SearchRange = [trayPyramid[0].shape[1] // 6,
                           trayPyramid[0].shape[0] // 6]
            score, loc, angle = cd.matchTemplatePyramid(
                self.imagePyramid,
                trayPyramid,
                RotationAngle=0,
                EstimatedLocation=self.trayPositions[i],
                SearchRange=SearchRange)
            if score < 0.3:
                # FIXME: For now we don't handle missing trays.
                raise PCExBrakeInPipeline(
                    self.actName,
                    "Low tray matching score. Likely tray %d is missing." % i)

            self.trayLocs.append(loc)

        # add tray location information
        context.outputwithimage["trayLocs"] = self.trayLocs

        tsi.pixels = self.image
        return([tsi, self.imagePyramid, self.trayLocs])
    def __exec__(self, context, *args):
        tsi = args[0]
        self.image = tsi.pixels
        temp = np.zeros_like(self.image)
        temp[:, :, :] = self.image[:, :, :]
        temp[:, :, 1] = 0  # suppress green channel
        self.imagePyramid = cd.createImagePyramid(temp)
        self.trayPyramids = []
        for i in range(self.trayNumber):
            # fixed tray image so that perspective postions of the trays are
            # fixed
            trayFile = os.path.join(context.ints.path,
                                    self.settingPath,
                                    self.trayFiles % i)
            trayImage = read_image(trayFile)
            if trayImage is None:
                LOG.error("Fail to read", trayFile)
            trayImage[:, :, 1] = 0  # suppress green channel
            trayImage = trayImage[:, :, 0:3]  # supress Alpha channel
            trayPyramid = cd.createImagePyramid(trayImage)
            self.trayPyramids.append(trayPyramid)

        self.trayLocs = []
        for i, trayPyramid in enumerate(self.trayPyramids):
            SearchRange = [trayPyramid[0].shape[1] // 6,
                           trayPyramid[0].shape[0] // 6]
            score, loc, angle = cd.matchTemplatePyramid(
                self.imagePyramid,
                trayPyramid,
                RotationAngle=0,
                EstimatedLocation=self.trayPositions[i],
                SearchRange=SearchRange)
            if score < 0.3:
                raise PCExCannotFindTray(i, tsi.path)

            self.trayLocs.append(loc)

        tsi.pixels = self.image
        return([tsi, self.imagePyramid, self.trayLocs])
 def __exec__(self, context, *args):
     tsi = args[0]
     self.image = tsi.pixels
     meanIntensity = np.mean(self.image)
     if meanIntensity < self.minIntensity:
         raise PCExImageTooDark(tsi.path)
     if not self.useWhiteBackground:
         self.imagePyramid = cd.createImagePyramid(self.image)
         ccdImg = read_image(self.ccf)[:, :, 0:3]
         if ccdImg is None:
             raise PCExBadImage(self.ccf)
         self.ccdPyramid = cd.createImagePyramid(ccdImg)
         # create image pyramid for multiscale matching
         SearchRange = [self.ccdPyramid[0].shape[1] * 1.5,
                        self.ccdPyramid[0].shape[0] * 1.5]
         score, loc, angle = cd.matchTemplatePyramid(
             self.imagePyramid, self.ccdPyramid,
             0, EstimatedLocation=self.colorcardPosition,
             SearchRange=SearchRange)
         if score > 0.3:
             # extract color information
             self.foundCard = self.image[
                 loc[1] - ccdImg.shape[0] // 2:loc[1] + ccdImg.shape[0] // 2,
                 loc[0] - ccdImg.shape[1] // 2:loc[0] + ccdImg.shape[1] // 2]
             self.ccdColors, _ = cd.getColorcardColors(self.foundCard,
                                                       GridSize=[6, 4])
             self.ccdParams = cd.estimateColorParameters(
                 self.colorcardTrueColors,
                 self.ccdColors)
             # Save colourcard image to instance
             self.colorcardImage = ccdImg
             # for displaying
             self.loc = loc
         else:
             raise PCExCannotFindColorCard(tsi.path)
     else:
         self.ccdParams = cd.estimateColorParametersFromWhiteBackground(
             self.image, self.backgroundWindow, self.maxIntensity)
     return([tsi, self.ccdParams])
    def __call__(self, context, *args):
        LOG.info(self.mess)
        tsi, self.imagePyramid, self.trayLocs = args
        self.image = tsi.pixels
        # read pot template image and scale to the pot size
        potFile = os.path.join(
            context.ints.path,
            self.settingPath,
            self.potFile)
        potImage = cv2.imread(potFile)[:, :, ::-1]
        potTemplateFile = os.path.join(
            context.ints.path,
            self.settingPath,
            self.potTemplateFile)
        potTemplateImage = cv2.imread(potTemplateFile)[:, :, ::-1]
        potTemplateImage[:, :, 1] = 0  # suppress green channel
        potTemplateImage = cv2.resize(
            potTemplateImage.astype(np.uint8),
            (potImage.shape[1],
             potImage.shape[0]))
        self.potPyramid = cd.createImagePyramid(potTemplateImage)

        XSteps = self.traySize[0] // self.potSize[0]
        YSteps = self.traySize[1] // self.potSize[1]
        StepX = self.traySize[0] // XSteps
        StepY = self.traySize[1] // YSteps

        self.potLocs2 = []
        self.potLocs2_ = []
        potGridSize = [4, 5]
        for trayLoc in self.trayLocs:
            if trayLoc is None:
                self.potLocs2.append(None)
                continue
            StartX = trayLoc[0] - self.traySize[0] // 2 + StepX // 2
            StartY = trayLoc[1] + self.traySize[1] // 2 - StepY // 2
            SearchRange = [self.potPyramid[0].shape[1] // 4,
                           self.potPyramid[0].shape[0] // 4]
#            SearchRange = [32, 32]
            locX = np.zeros(potGridSize)
            locY = np.zeros(potGridSize)
            for k in range(potGridSize[0]):
                for l in range(potGridSize[1]):
                    estimateLoc = [StartX + StepX * k, StartY - StepY * l]
                    score, loc, angle = cd.matchTemplatePyramid(
                        self.imagePyramid,
                        self.potPyramid,
                        RotationAngle=0,
                        EstimatedLocation=estimateLoc,
                        NoLevels=3,
                        SearchRange=SearchRange)
                    locX[k, l], locY[k, l] = loc

            # correct for detection error
            potLocs = []
            potLocs_ = []
            diffXX = locX[1:, :] - locX[:-1, :]
            diffXY = locX[:, 1:] - locX[:, :-1]
            diffYX = locY[1:, :] - locY[:-1, :]
            diffYY = locY[:, 1:] - locY[:, :-1]
            diffXXMedian = np.median(diffXX)
            diffXYMedian = np.median(diffXY)
            diffYXMedian = np.median(diffYX)
            diffYYMedian = np.median(diffYY)
            for k in range(potGridSize[0]):
                for l in range(potGridSize[1]):
                    locX[k, l] = trayLoc[0] + diffXXMedian * (k - (potGridSize[0] - 1.0) / 2.0) + \
                        diffXYMedian * (l - (potGridSize[1] - 1.0) / 2.0)
                    locY[k, l] = trayLoc[1] + diffYXMedian * (k - (potGridSize[0] - 1.0) / 2.0) + \
                        diffYYMedian * (l - (potGridSize[1] - 1.0) / 2.0)
                    # this fixes perpective shift
                    # TODO: need a more elegant solution
                    locY[k, l] = locY[k, l] + 10

                    potLocs.append([locX[k, l], locY[k, l]])
                    potLocs_.append(estimateLoc)
            self.potLocs2.append(potLocs)
            self.potLocs2_.append(potLocs_)

        # Create a new ImagePotMatrix with newly discovered locations
        ipmPrev = None
        if context.hasSubSecName("ipmPrev"):
            ipmPrev = context.ipmPrev

        flattened = list(chain.from_iterable(self.potLocs2))
        growM = round(min(spatial.distance.pdist(flattened)) / 2)
        tsi.ipm = tm_pot.ImagePotMatrix(
            tsi,
            pots=[],
            growM=growM,
            ipmPrev=ipmPrev)
        potID = 1
        for tray in self.potLocs2:
            trayID = 1
            for center in tray:
                r = tm_pot.ImagePotRectangle(
                    center,
                    tsi.pixels.shape,
                    growM=growM)
                p = tm_pot.ImagePotHandler(potID, r, tsi.ipm)
                p.setMetaId("trayID", trayID)
                tsi.ipm.addPot(p)
                potID += 1
                trayID += 1

        context.outputwithimage["potLocs"] = self.potLocs2
        return([tsi])
    def __exec__(self, context, *args):
        tsi, self.imagePyramid, self.trayLocs = args
        self.image = tsi.pixels
        # read pot template image and scale to the pot size
        potFile = os.path.join(
            context.ints.path,
            self.settingPath,
            self.potFile)
        potImage = read_image(potFile)
        potTemplateFile = os.path.join(
            context.ints.path,
            self.settingPath,
            self.potTemplateFile)
        potTemplateImage = read_image(potTemplateFile)
        potTemplateImage[:, :, 1] = 0  # suppress green channel
        potTemplateImage = cv2.resize(
            potTemplateImage.astype(np.uint8),
            (potImage.shape[1],
             potImage.shape[0]))
        self.potPyramid = cd.createImagePyramid(potTemplateImage)

        XSteps = int(round(self.traySize[0] / float(self.potSize[0])))
        YSteps = int(round(self.traySize[1] / float(self.potSize[1])))
        StepX = self.traySize[0] // XSteps
        StepY = self.traySize[1] // YSteps

        self.potLocs2 = []
        self.potLocs2_ = []
        potGridSize = [4, 5]
        for trayLoc in self.trayLocs:
            if trayLoc is None:
                self.potLocs2.append(None)
                continue
            StartX = trayLoc[0] - self.traySize[0] // 2 + StepX // 2
            StartY = trayLoc[1] + self.traySize[1] // 2 - StepY // 2
            SearchRange = [self.potPyramid[0].shape[1] // 4,
                           self.potPyramid[0].shape[0] // 4]
            # SearchRange = [32, 32]
            locX = np.zeros(potGridSize)
            locY = np.zeros(potGridSize)
            for k in range(potGridSize[0]):
                for l in range(potGridSize[1]):
                    estimateLoc = [StartX + StepX * k, StartY - StepY * l]
                    score, loc, angle = cd.matchTemplatePyramid(
                        self.imagePyramid,
                        self.potPyramid,
                        RotationAngle=0,
                        EstimatedLocation=estimateLoc,
                        NoLevels=3,
                        SearchRange=SearchRange)
                    locX[k, l], locY[k, l] = loc

            # correct for detection error
            potLocs = []
            potLocs_ = []
            diffXX = locX[1:, :] - locX[:-1, :]
            diffXY = locX[:, 1:] - locX[:, :-1]
            diffYX = locY[1:, :] - locY[:-1, :]
            diffYY = locY[:, 1:] - locY[:, :-1]
            diffXXMedian = np.median(diffXX)
            diffXYMedian = np.median(diffXY)
            diffYXMedian = np.median(diffYX)
            diffYYMedian = np.median(diffYY)
            for k in range(potGridSize[0]):
                for l in range(potGridSize[1]):
                    locX[k, l] = trayLoc[0] + diffXXMedian * (k - (potGridSize[0] - 1.0) / 2.0) + \
                        diffXYMedian * (l - (potGridSize[1] - 1.0) / 2.0)
                    locY[k, l] = trayLoc[1] + diffYXMedian * (k - (potGridSize[0] - 1.0) / 2.0) + \
                        diffYYMedian * (l - (potGridSize[1] - 1.0) / 2.0)
                    # this fixes perpective shift
                    # TODO: need a more elegant solution
                    locY[k, l] = locY[k, l] + 10

                    potLocs.append([locX[k, l], locY[k, l]])
                    potLocs_.append(estimateLoc)
            self.potLocs2.append(potLocs)
            self.potLocs2_.append(potLocs_)

        # Create a new ImagePotMatrix with newly discovered locations
        ipmPrev = None
        if context.hasSubSecName("ipmPrev"):
            ipmPrev = context.ipmPrev

        # Calculate growM with potSize from potdetect component.
        growM = 0
        if isinstance(self.potSize, list) and len(self.potSize) == 2:
            growM = round(max(self.potSize) / 2)
        else:
            # if no user vals, we try to calculate it.
            flattened = list(chain.from_iterable(self.potLocs2))
            sortDist = np.sort(spatial.distance.pdist(flattened))
            sortDist = sortDist[0:len(flattened)]
            growM = round(np.median(sortDist) / 2)

        tsi.ipm = tm_pot.ImagePotMatrix(
            tsi, pots=[], growM=growM, ipmPrev=ipmPrev)
        potID = self.startingPotId
        for tray in self.potLocs2:
            trayID = 1
            for c in tray:  # c => center
                m = dict([[x, context.metas.getVal(x)[potID]]
                        for x in context.metas.listSubSecNames()
                        if potID in context.metas.getVal(x).keys()])
                try:
                    r = tm_pot.ImagePotRectangle(c, tsi.pixels.shape,
                        growM=growM)
                except:
                    raise PCExPotRectangleDimsOutOfImage(potID, c,
                        tsi.pixels.shape)

                p = tm_pot.ImagePotHandler(potID, r, tsi.ipm, metaids=m)
                p.setMetaId("trayID", trayID)
                tsi.ipm.addPot(p)
                potID += 1
            trayID += 1

        return([tsi])