예제 #1
0
 def setExposure(self, exposure):
     if self.connected:
         try:
             self.camHandle.ExposureTime = exposure
         except genicam.GenericException:
             self.connected = False
             raise errors.CameraError("Camera communication failed")
     else:
         log.message(DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 0,
                     'Trying to set the exposure of an unconnected camera')
예제 #2
0
def getAvailableCameraIDs():
    try:
        available_cameras = pypylon.TlFactory.GetInstance().EnumerateDevices()
        available_ids = []

        for i in range(0, len(available_cameras)):
            available_ids.append(int(available_cameras[i].GetSerialNumber()))
        return available_ids
    except genicam.GenericException:
        self.connected = False
        raise errors.CameraError("Camera communication failed")
예제 #3
0
 def setProperties(self, exposure, gain, blackLevel, gamma):
     if self.connected:
         #modify properties
         try:
             self.camHandle.ExposureTime = exposure
             self.camHandle.Gain = gain
             self.camHandle.BlackLevel = blackLevel
             self.camHandle.Gamma = gamma
         except genicam.GenericException:
             self.connected = False
             raise errors.CameraError("Camera communication failed")
     else:
         log.message(
             DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 0,
             'Trying to set the properties of an unconnected camera')
예제 #4
0
 def setMaxROI(self):
     if self.connected:
         try:
             self.parameters.ROICenter = (self.parameters.maxX,
                                          self.parameters.maxY)
             self.parameters.validityRadius = DEFINES.PC_IMAGE_GET_ALL_ROI
             self.parameters.ROIoffsetX = 0
             self.parameters.ROIoffsetY = 0
             self.parameters.ROIwidth = self.parameters.maxX
             self.parameters.ROIheight = self.parameters.maxY
             self.camHandle.OffsetX = 0
             self.camHandle.Width = self.camHandle.Width.Max
             self.camHandle.OffsetY = 0
             self.camHandle.Height = self.camHandle.Height.Max
         except genicam.GenericException:
             self.connected = False
             raise errors.CameraError("Camera communication failed")
     else:
         log.message(DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 0,
                     'Trying to set the ROI of an unconnected camera')
예제 #5
0
    def connect(self, cameraType=None, compatibleCameraID=None):
        if not self.connected or not (self.parameters.cameraType == cameraType
                                      ) or not (self.parameters.ID
                                                == compatibleCameraID):
            #If we want to change the camera, close the currently connected one
            if self.connected:
                try:
                    self.camHandle.close()
                except genicam.GenericException:
                    pass
            #Connect to the new camera
            try:
                if cameraType == None:
                    raise TypeError

                #initalize the camera
                tlf = pypylon.TlFactory.GetInstance()

                available_cameras = tlf.EnumerateDevices()
                available_ids = np.zeros(len(available_cameras))

                for i in range(0, len(available_cameras)):
                    available_ids[i] = available_cameras[i].GetSerialNumber()
                    if available_ids[
                            i] == compatibleCameraID or compatibleCameraID == None:
                        cameraAlreadyUsed = False
                        try:
                            self.camHandle = pypylon.InstantCamera(
                                tlf.CreateDevice(available_cameras[i]))
                        except genicam.GenericException:
                            cameraAlreadyUsed = True
                            log.message(
                                DEFINES.LOG_MESSAGE_PRIORITY_WARNING, 0,
                                f'Camera {available_ids[i]:.0f} is already used in another application'
                            )
                            if not compatibleCameraID == None:
                                raise errors.CameraError(
                                    "No compatible camera could be found"
                                ) from None  #If this was a specific ID search, break

                        if not cameraAlreadyUsed:
                            self.camHandle.Open()

                            #configure default camera settings
                            self.camHandle.PixelFormat = DEFINES.PC_CAMERA_PIXEL_FORMAT
                            self.camHandle.OffsetX = 0
                            self.camHandle.OffsetY = 0
                            self.camHandle.Width = self.camHandle.Width.Max
                            self.camHandle.Height = self.camHandle.Height.Max

                            self.parameters.cameraType = cameraType
                            self.parameters.maxX = self.camHandle.Width.Max
                            self.parameters.maxY = self.camHandle.Height.Max
                            self.parameters.ID = int(available_ids[i])

                            if cameraType == DEFINES.PC_CAMERA_TYPE_XY:
                                self.parameters.nbImagesToGrab = DEFINES.PC_CAMERA_XY_NB_IMAGES_PER_POINT
                                self.parameters.minCropWindow = DEFINES.PC_CAMERA_XY_MIN_CROP_WINDOW
                            else:
                                self.parameters.nbImagesToGrab = DEFINES.PC_CAMERA_TILT_NB_IMAGES_PER_POINT
                                self.parameters.minCropWindow = DEFINES.PC_CAMERA_FORBID_CROPPING

                            if self.parameters.minCropWindow == DEFINES.PC_CAMERA_FORBID_CROPPING:
                                self.parameters.minCropWindow = np.max(
                                    self.parameters.maxX, self.parameters.maxY)

                            if self.camHandle.GetDeviceInfo().GetModelName(
                            ) == 'acA5472-17um':  #Require soft ROI for the acA5472-17um cameras
                                self.parameters.softROIrequired = True

                            self.connected = True
                            return

                if not self.connected:
                    raise errors.CameraError(
                        "No compatible camera could be found"
                    ) from None  #If this was a specific ID search, break

            except errors.CameraError as e:
                log.message(DEFINES.LOG_MESSAGE_PRIORITY_ERROR, 0, str(e))
                raise errors.CameraError(
                    "Camera initialization failed") from None
            except genicam.GenericException:
                raise errors.CameraError(
                    "Camera initialization failed") from None
예제 #6
0
def main():
    import matplotlib.image as mpimg
    import matplotlib.pyplot as plt
    from computeCentroid import compute_centroid as compute_centroid
    import classConfig

    # try:
    #   try:
    #       raise OSError
    #   except OSError:
    #       raise errors.CameraError("error1")

    #   try:
    #       raise OSError
    #   except OSError:
    #       raise errors.CameraError("error2")
    # except Exception as e:
    #   print(e)

    #Set the default values
    im_path = os.path.join('Python_garbage', 'garbage.png')

    nbCentroidsLoop = 1000
    ncComputationsPerCentroid = 1
    centroids_txt_path = os.path.join('Python_garbage', 'centroids.mat')

    image_ID = 1
    exposure_time = 250
    gain = 0.0
    black_level = 1.25
    gamma = 1.0

    ROI = np.zeros(5, dtype=np.uint16)

    #python grab_image.py "" "..\41000-Matlab-Calibration_and_test\calibration_data_cam1_XY.mat" 1 12345 4 11111 2 2.5 1.5 1.5
    nb_args = len(sys.argv) - 1

    if nb_args > 0:
        im_path = sys.argv[1]
    if nb_args > 1:
        cam_path = sys.argv[2]
    if nb_args > 2:
        camera_ID = int(sys.argv[3])
    if nb_args > 3:
        image_ID = int(sys.argv[4])
    if nb_args > 4:
        nb_images = int(sys.argv[5])
    if nb_args > 5:
        exposure_time = float(sys.argv[6])
    if nb_args > 6:
        gain = float(sys.argv[7])
    if nb_args > 7:
        black_level = float(sys.argv[8])
    if nb_args > 8:
        gamma = float(sys.argv[9])

    if im_path != '' or image_ID > -1:
        centroid = (0, 0, 0, 0, 0, 0, 0, 0)

        try:
            #create camera instance
            camera = Camera(cameraType=DEFINES.PC_CAMERA_TYPE_XY,
                            compatibleCameraID=22289804)  #22942361 #22994237

            #_=os.system('echo Taking picture')
            camera.setMaxROI()
            exposure_time = camera.getOptimalExposure(exposure_time)
            log.message(DEFINES.LOG_MESSAGE_PRIORITY_INFO, 0,
                        f'Exposure time is: {exposure_time:.1f}')
            if exposure_time >= DEFINES.PC_CAMERA_XY_MAX_EXPOSURE:
                log.message(DEFINES.LOG_MESSAGE_PRIORITY_ERROR, 0,
                            f'Max exposure was reached')
                camera.close()
                return
            camera.setProperties(exposure_time, gain, black_level, gamma)

            if image_ID > -1:
                config = classConfig.Config()
                camera.setDistortionCorrection(config)

            centroids = np.zeros((nbCentroidsLoop, 3))
            minimum = 1000000 * np.ones(2)
            maximum = 0 * np.ones(2)
            mean = 0 * np.ones(2)
            std = 0 * np.ones(2)

            #Get first centroid to set ROI
            picture = camera.getImage()

            #Save the image
            if im_path != '':
                mpimg.imsave(im_path, picture)

            #compute the centroid
            if image_ID > -1:
                centroid = compute_centroid(picture, camera.parameters,
                                            image_ID)

            if np.isnan(centroid[0]):
                log.message(DEFINES.LOG_MESSAGE_PRIORITY_WARNING, 0,
                            "No centroid detected")
                return

            ROI[0] = int(centroid[2])
            ROI[1] = int(centroid[3])
            ROI[2] = camera.parameters.minCropWindow + 20
            ROI[3] = camera.parameters.minCropWindow
            ROI[4] = np.sqrt(ROI[2]**2 + ROI[3]**2)

            camera.setROI(ROI)
            print("camera params", camera.parameters)

            for i in range(0, nbCentroidsLoop):
                currentComputation = []
                for j in range(0, ncComputationsPerCentroid):
                    t0 = time.perf_counter()
                    picture = camera.getImage()

                    #Save the image
                    if im_path != '':
                        mpimg.imsave(im_path, picture)

                    #compute the centroid
                    t1 = time.perf_counter()
                    if image_ID > -1:
                        currentComputation.append(
                            compute_centroid(picture, camera.parameters,
                                             image_ID))

                    # log.message(DEFINES.LOG_MESSAGE_PRIORITY_WARNING, 0, f'Image: {t1-t0:4.3f} s. Centroid: {time.perf_counter()-t1:4.3f} s')

                    if np.isnan(centroid[0]):
                        log.message(DEFINES.LOG_MESSAGE_PRIORITY_WARNING, 0,
                                    "No centroid detected")
                        raise errors.CameraError("Fiber light went out")

                currentComputation = np.array(currentComputation)
                # print(currentComputation)
                # print(currentComputation[0])
                # print(currentComputation[0,0])

                centroid = (np.mean(currentComputation[:,0]),\
                            np.mean(currentComputation[:,1]),\
                            np.mean(currentComputation[:,2]),\
                            np.mean(currentComputation[:,3]),\
                            np.mean(currentComputation[:,4]),\
                            np.mean(currentComputation[:,5]),\
                            np.mean(currentComputation[:,6]),\
                            currentComputation[0,7])

                centroids[i, 2] = i
                for j in range(0, 2):
                    centroids[i, j] = centroid[j]
                    if centroid[j] < minimum[j]:
                        minimum[j] = centroid[j]
                    if centroid[j] > maximum[j]:
                        maximum[j] = centroid[j]
                    mean[j] = np.mean(centroids[0:(i + 1), j])
                    std[j] = np.std(centroids[0:(i + 1), j])

                log.message(DEFINES.LOG_MESSAGE_PRIORITY_INFO, 0,   f'{centroid[0]:.6f},{centroid[1]:.6f},{centroid[6]:.6f}'+\
                                                                    f' Centroid {i+1:4}/{nbCentroidsLoop:4}'+\
                                                                    f' Max diff: {maximum[0]-minimum[0]:.6f},{maximum[1]-minimum[1]:.6f}'+\
                                                                    f' Mean: {mean[0]:.6f},{mean[1]:.6f}'+\
                                                                    f' STD: {std[0]:.6f},{std[1]:.6f}')

            centroids[:, 0] = centroids[:, 0] - np.nanmean(centroids[:, 0])
            centroids[:, 1] = centroids[:, 1] - np.nanmean(centroids[:, 1])

        except errors.CameraError as e:
            log.message(DEFINES.LOG_MESSAGE_PRIORITY_CRITICAL, 0, str(e))
            log.stop()
            return

        try:
            io.savemat(centroids_txt_path, \
                {'centroids': centroids})
        except OSError as e:
            log.message(DEFINES.LOG_MESSAGE_PRIORITY_CRITICAL, 0, str(e))
            log.stop()
            return

        camera.close()

        plt.figure()

        plt.scatter(centroids[:, 0],
                    centroids[:, 1],
                    color='red',
                    marker='x',
                    s=1)
        plt.show()
예제 #7
0
    def getOptimalExposure(self, initExposure):
        if not self.connected:
            raise errors.CameraError("Camera is not connected")
        else:
            try:
                #init loop
                i = 1
                nbOk = 0
                if self.parameters.cameraType == DEFINES.PC_CAMERA_TYPE_XY:
                    maxExposure = DEFINES.PC_CAMERA_XY_MAX_EXPOSURE
                else:
                    maxExposure = DEFINES.PC_CAMERA_GET_EXPOSURE_EXPOSURE_MAX

                currentExposure = initExposure

                self.camHandle.ExposureTime = currentExposure

                #grab images and adapt exposure
                while i <= DEFINES.PC_CAMERA_GET_EXPOSURE_MAX_ITERATIONS:
                    #get one image

                    image = self.camHandle.GrabOne(DEFINES.PC_IMAGE_TIMEOUT)
                    image = np.divide(image.Array,
                                      DEFINES.PC_CAMERA_MAX_INTENSITY_RAW)

                    #crop validity circle

                    validityCenter = (self.parameters.ROICenter[0] -
                                      self.camHandle.OffsetX.Value,
                                      self.parameters.ROICenter[1] -
                                      self.camHandle.OffsetY.Value)
                    image, offsetX, offsetY = self.computeValidSoftROI(
                        image, validityCenter, self.parameters.validityRadius)

                    #filter the image with a gaussian filter
                    if self.parameters.cameraType == DEFINES.PC_CAMERA_TYPE_XY:
                        image = gaussianFilter(
                            image, DEFINES.CC_IMAGE_XY_FILTERING_SIGMA)
                    else:
                        image = gaussianFilter(
                            image, DEFINES.CC_IMAGE_TILT_FILTERING_SIGMA)

                    maxPxIntensity = np.max(image)

                    #Check the stopping criterias
                    if (maxPxIntensity >= DEFINES.PC_CAMERA_GET_EXPOSURE_TARGET_INTENSITY-DEFINES.PC_CAMERA_GET_EXPOSURE_INTENSITY_TOLERANCE and \
                        maxPxIntensity <= DEFINES.PC_CAMERA_GET_EXPOSURE_TARGET_INTENSITY+DEFINES.PC_CAMERA_GET_EXPOSURE_INTENSITY_TOLERANCE) or \
                        currentExposure == DEFINES.PC_CAMERA_GET_EXPOSURE_EXPOSURE_MIN or \
                        currentExposure == maxExposure:
                        nbOk += 1

                    #Check if the stopping condition is reached
                    if nbOk >= DEFINES.PC_CAMERA_GET_EXPOSURE_NB_OK:
                        return currentExposure

                    #Adapt the exposure
                    if maxPxIntensity >= DEFINES.PC_CAMERA_GET_EXPOSURE_SATURED_THRESHOLD:
                        currentExposure = currentExposure * DEFINES.PC_CAMERA_GET_EXPOSURE_TARGET_INTENSITY / maxPxIntensity * DEFINES.PC_CAMERA_GET_EXPOSURE_SATURED_GAIN  #if we are satured, decrease exposure faster
                    else:
                        currentExposure = currentExposure * DEFINES.PC_CAMERA_GET_EXPOSURE_TARGET_INTENSITY / maxPxIntensity

                    if currentExposure < DEFINES.PC_CAMERA_GET_EXPOSURE_EXPOSURE_MIN:
                        currentExposure = DEFINES.PC_CAMERA_GET_EXPOSURE_EXPOSURE_MIN
                    elif currentExposure > maxExposure:
                        currentExposure = maxExposure

                    self.camHandle.ExposureTime = currentExposure
                    i = i + 1

                return currentExposure
            except genicam.GenericException:
                self.connected = False
                raise errors.CameraError(
                    "Camera communication failed during optimal exposure determination"
                )
예제 #8
0
    def getImage(self, computationManager=None, imageID=None):
        if not self.connected:
            raise errors.CameraError("Camera is not connected") from None
        else:
            try:
                #Initialize result container
                i = 0
                result = np.zeros(
                    (self.camHandle.Height.Value, self.camHandle.Width.Value),
                    dtype=np.uint16)
                #grab images
                # t0 = time.perf_counter()

                self.camHandle.StartGrabbingMax(self.parameters.nbImagesToGrab)
                # t1 = time.perf_counter()
                # print(f'StartGrab\t\t\t{t1-t0:3.3f}')
                while self.camHandle.IsGrabbing():
                    # t2 = time.perf_counter()
                    grabResult = self.camHandle.RetrieveResult(
                        DEFINES.PC_IMAGE_TIMEOUT,
                        pypylon.TimeoutHandling_Return)

                    # t3 = time.perf_counter()

                    if grabResult.GrabSucceeded():
                        result = np.add(grabResult.Array, result)
                        grabResult.Release()
                        i = i + 1
                    # t4 = time.perf_counter()
                    # print(f'RetrieveResult\t\t\t{t3-t2:3.3f}')
                    # print(f'Add and release result\t\t{t4-t3:3.3f}')

                # t5 = time.perf_counter()
                # print(f'Total grab\t\t\t{t5-t0:3.3f}')
                #crop validity circle
                if self.parameters.validityRadius != DEFINES.PC_IMAGE_GET_ALL_ROI:
                    validityCenter = (self.parameters.ROICenter[0] -
                                      self.camHandle.OffsetX.Value,
                                      self.parameters.ROICenter[1] -
                                      self.camHandle.OffsetY.Value)
                    circularMask = mm.create_circular_mask(
                        result.shape[0], result.shape[1], validityCenter,
                        self.parameters.validityRadius)

                    result[~circularMask] = 0
                # t6 = time.perf_counter()
                # print(f'Precropping circle\t\t{t6-t5:3.3f}')
                image = np.divide(result, i)
                # t7 = time.perf_counter()
                # print(f'NP Divide image\t\t\t{t7-t6:3.3f}')
                #directly send to computation queue if asked for
                if computationManager is not None:
                    computationManager.put_in_centroid_queue(
                        (image, self.parameters.ROIoffsetX,
                         self.parameters.ROIoffsetY, imageID),
                        block=True)
                # t8 = time.perf_counter()
                # print(f'Total execution\t\t\t{t8-t0:3.3f}')
                #return image
                return image
            except (genicam.GenericException, SystemError):
                self.connected = False
                raise errors.CameraError(
                    "Camera communication failed during image grabbing")
예제 #9
0
 def getROI(self):
     if not self.connected:
         raise errors.CameraError("Camera is not connected") from None
     else:
         return self.parameters.ROIoffsetX, self.parameters.ROIoffsetY, self.parameters.ROIwidth, self.parameters.ROIheight
예제 #10
0
    def setROI(self, ROI):
        if self.connected:
            if ROI[0] > self.parameters.maxX or ROI[0] < 0 or ROI[
                    1] > self.parameters.maxY or ROI[1] < 0:
                raise errors.OutOfRangeError(
                    "Specified camera ROI is out of range")
                return

            try:
                x_min = int(ROI[0] - ROI[2] / 2)
                x_max = int(ROI[0] + ROI[2] / 2)
                y_min = int(ROI[1] - ROI[3] / 2)
                y_max = int(ROI[1] + ROI[3] / 2)

                #crop ROI while it is not in the image, up to the minimal window allowed
                if x_min < 0:
                    x_min = 0
                if x_max - x_min < self.parameters.minCropWindow:
                    x_max = x_min + self.parameters.minCropWindow
                if x_max > self.parameters.maxX:
                    x_max = self.parameters.maxX
                if x_max - x_min < self.parameters.minCropWindow:
                    x_min = x_max - self.parameters.minCropWindow
                if y_min < 0:
                    y_min = 0
                if y_max - y_min < self.parameters.minCropWindow:
                    y_max = y_min + self.parameters.minCropWindow
                if y_max > self.parameters.maxY:
                    y_max = self.parameters.maxY
                if y_max - y_min < self.parameters.minCropWindow:
                    y_min = y_max - self.parameters.minCropWindow

                if self.camHandle.GetDeviceInfo().GetModelName(
                ) == 'acA5472-17um':  #Strangly, the acA5472-17um camera needs a multiple of 4 for Xoffset and width
                    x_min = x_min - x_min % 4
                    width = x_max - x_min
                    width = width - width % 4
                else:
                    width = x_max - x_min

                height = y_max - y_min

                self.parameters.ROICenter = (ROI[0], ROI[1])
                self.parameters.validityRadius = ROI[4]
                self.parameters.ROIoffsetX = x_min
                self.parameters.ROIoffsetY = y_min
                self.parameters.ROIwidth = width
                self.parameters.ROIheight = height

                #set the ROI properties
                if self.camHandle.OffsetX.Value + width < self.parameters.maxX:
                    self.camHandle.Width = width
                    self.camHandle.OffsetX = x_min
                else:
                    self.camHandle.OffsetX = x_min
                    self.camHandle.Width = width

                if self.camHandle.OffsetY.Value + height < self.parameters.maxY:
                    self.camHandle.Height = height
                    self.camHandle.OffsetY = y_min
                else:
                    self.camHandle.OffsetY = y_min
                    self.camHandle.Height = height
            except genicam.GenericException:
                self.connected = False
                raise errors.CameraError("Camera communication failed")
        else:
            log.message(DEFINES.LOG_MESSAGE_PRIORITY_DEBUG_WARNING, 0,
                        'Trying to set the ROI of an unconnected camera')