コード例 #1
0
def test_arduino_devmode():
    """Tests the Arduino DevMode.

    The first test will instantiate DevMode objects with various switch 
    configurations. The returned objects should not be None.

    The second test write a command to the mailbox and read another command
    from the mailbox. Test whether the write and the read are successful.

    """
    ol = Overlay('base.bit')

    for mb_info in [ARDUINO]:
        assert Arduino_DevMode(mb_info, ARDUINO_SWCFG_DIOALL) is not None
        ol.reset()

        # Initiate the Microblaze
        microblaze = Arduino_DevMode(mb_info, ARDUINO_SWCFG_DIOALL)
        microblaze.start()
        assert microblaze.status() == "RUNNING"

        # Test whether writing is successful
        data = 0
        microblaze.write_cmd(ARDUINO_DIO_BASEADDR + ARDUINO_DIO_TRI_OFFSET,
                             ARDUINO_CFG_DIO_ALLOUTPUT)
        microblaze.write_cmd(ARDUINO_DIO_BASEADDR + ARDUINO_DIO_DATA_OFFSET,
                             data)

        # Test whether reading is successful
        microblaze.write_cmd(ARDUINO_DIO_BASEADDR + ARDUINO_DIO_TRI_OFFSET,
                             ARDUINO_CFG_DIO_ALLINPUT)
        data = microblaze.read_cmd(ARDUINO_DIO_BASEADDR +
                                   ARDUINO_DIO_DATA_OFFSET)
        assert data is not None

        # Stop the Microblaze
        microblaze.stop()
        assert microblaze.status() == "STOPPED"
        ol.reset()

    del ol
コード例 #2
0
def test_pmod_microblaze():
    """Test for the Pmod class.

    There are 3 tests done here:

    1. Test whether `Pmod()` can return an object without errors. 

    2. Calling `Pmod()` should not raise any exception if the previous Pmod
    object runs the same program.

    3. Creates multiple Pmod instances on the same fixed ID. Exception should
    be raised in this case.
    
    """
    ol = Overlay('base.bit')

    for mb_info in [PMODA, PMODB]:
        exception_raised = False
        try:
            _ = Pmod(mb_info, 'pmod_mailbox.bin')
        except RuntimeError:
            exception_raised = True
        assert not exception_raised, 'Should not raise exception.'
        ol.reset()

        exception_raised = False
        _ = Pmod(mb_info, 'pmod_mailbox.bin')
        try:
            _ = Pmod(mb_info, 'pmod_mailbox.bin')
        except RuntimeError:
            exception_raised = True
        assert not exception_raised, 'Should not raise exception.'
        ol.reset()

        exception_raised = False
        _ = Pmod(mb_info, 'pmod_dac.bin')
        try:
            _ = Pmod(mb_info, 'pmod_adc.bin')
        except RuntimeError:
            exception_raised = True
        assert exception_raised, 'Should raise exception.'
        ol.reset()

    del ol
コード例 #3
0
def test_arduino_microblaze():
    """Test for the Arduino class.

    There are 3 tests done here:

    1. Test whether `Arduino()` can return an object without errors. 

    2. Calling `Arduino()` should not raise any exception if the previous 
    Arduino object runs the same program.

    3. Creates multiple Arduino instances on the same fixed ID. Exception 
    should be raised in this case.
    
    """
    ol = Overlay('base.bit')

    for mb_info in [ARDUINO]:
        exception_raised = False
        try:
            _ = Arduino(mb_info, 'arduino_mailbox.bin')
        except RuntimeError:
            exception_raised = True
        assert not exception_raised, 'Should not raise exception.'
        ol.reset()

        exception_raised = False
        _ = Arduino(mb_info, 'arduino_mailbox.bin')
        try:
            _ = Arduino(mb_info, 'arduino_mailbox.bin')
        except RuntimeError:
            exception_raised = True
        assert not exception_raised, 'Should not raise exception.'
        ol.reset()

        exception_raised = False
        _ = Arduino(mb_info, 'arduino_analog.bin')
        try:
            _ = Arduino(mb_info, 'arduino_lcd18.bin')
        except RuntimeError:
            exception_raised = True
        assert exception_raised, 'Should raise exception.'
        ol.reset()

    del ol
コード例 #4
0
class cv2pynq():
    MAX_WIDTH = 1920
    MAX_HEIGHT = 1080

    def __init__(self, load_overlay=True):
        self.bitstream_name = None
        self.bitstream_name = "cv2pynq03.bit"
        self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR,
                                           self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.xlnk = Xlnk()
        self.partitions = 10  #split the cma into partitions for pipelined transfer
        self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions
        self.listOfcma = [
            self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions),
                                       self.MAX_WIDTH),
                                dtype=np.uint8) for i in range(self.partitions)
        ]
        self.img_filters = self.ol.image_filters
        self.dmaOut = self.img_filters.axi_dma_0.sendchannel
        self.dmaIn = self.img_filters.axi_dma_0.recvchannel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()
        self.filter2DType = -1  # filter types: SobelX=0, SobelY=1, ScharrX=2, ScharrY=3, Laplacian1=4, Laplacian3=5
        self.filter2D_5Type = -1  # filter types: SobelX=0, SobelY=1,                     Laplacian5=4
        self.filter2DfType = -1  # filter types: blur=0, GaussianBlur=1
        self.ffi = FFI()
        self.f2D = self.img_filters.filter2D_hls_0
        self.f2D.reset()
        self.f2D_5 = self.img_filters.filter2D_hls_5_0
        self.f2D_5.reset()
        self.f2D_f = self.img_filters.filter2D_f_0
        self.f2D_f.reset()
        self.erodeIP = self.img_filters.erode_hls_0
        self.erodeIP.reset()
        self.dilateIP = self.img_filters.dilate_hls_0
        self.dilateIP.reset()
        self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer0.init(self.cmaBuffer_0)
        self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer1.init(self.cmaBuffer_1)
        self.cmaBuffer_2 = self.xlnk.cma_array(
            shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH),
            dtype=np.uint8)  # *4 for CornerHarris return
        self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer2.init(self.cmaBuffer_2)
        self.CannyIP = self.img_filters.canny_edge_0
        self.CannyIP.reset()
        #self.cornerHarrisIP = self.img_filters.CornerHarris_hls_0
        #self.cornerHarrisIP.reset()

    def close(self):
        #self.dmaOut.stop()
        #self.dmaIn.stop()
        self.cmaBuffer_0.close()
        self.cmaBuffer_1.close()
        self.cmaBuffer_2.close()
        for cma in self.listOfcma:
            cma.close()

    def Sobel(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if (dx == 1) and (dy == 0):
                if self.filter2DType != 0:
                    self.filter2DType = 0
                    self.f2D.r1 = 0x000100ff  #[-1  0  1]
                    self.f2D.r2 = 0x000200fe  #[-2  0  2]
                    self.f2D.r3 = 0x000100ff  #[-1  0  1]
            elif (dx == 0) and (dy == 1):
                if self.filter2DType != 1:
                    self.filter2DType = 1
                    self.f2D.r1 = 0x00fffeff  #[-1 -2 -1]
                    self.f2D.r2 = 0x00000000  #[ 0  0  0]
                    self.f2D.r3 = 0x00010201  #[ 1  2  1]
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(1)
            self.f2D.start()
            return self.filter2D(src, dst)
        else:  #ksize == 5
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if (dx == 1) and (dy == 0):
                if self.filter2D_5Type != 0:
                    self.filter2D_5Type = 0
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-6,  -12,  0,    12,   6,

                    0xfa, 0xf4, 0x00, 0x0c, 0x06, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    0,0,0]) #fill up to allign with 4
            elif (dx == 0) and (dy == 1):
                if self.filter2D_5Type != 1:
                    self.filter2D_5Type = 1
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -4,   -6,   -4,   -1,

                    0xff, 0xfc, 0xfa, 0xfc, 0xff, \
                    #-2,  -8,   -12,  -8,   -2,

                    0xfe, 0xf8, 0xf4, 0xf8, 0xfe, \
                    # 0,  0,    0,    0,    0,

                    0x00, 0x00, 0x00, 0x00, 0x00, \
                    # 2,  8,    12,   8,    2,

                    0x02, 0x08, 0x0c, 0x08, 0x02, \
                    # 1,  4,    6,    4,    1,

                    0x01, 0x04, 0x06, 0x04, 0x01, \
                    0,0,0]) #fill up to allign with 4
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(5)
            self.f2D_5.start()
            return self.filter2D(src, dst)

    def Scharr(self, src, ddepth, dx, dy, dst):
        self.f2D.rows = src.shape[0]
        self.f2D.columns = src.shape[1]
        self.f2D.channels = 1
        if (dx == 1) and (dy == 0):
            if self.filter2DType != 2:
                self.filter2DType = 2
                self.f2D.r1 = 0x000300fd  #[-3  0  3]
                self.f2D.r2 = 0x000a00f6  #[-10 0 10]
                self.f2D.r3 = 0x000300fd  #[-3  0  3]
        elif (dx == 0) and (dy == 1):
            if self.filter2DType != 3:
                self.filter2DType = 3
                self.f2D.r1 = 0x00fdf6fd  #[-3 -10 -3]
                self.f2D.r2 = 0x00000000  #[ 0   0  0]
                self.f2D.r3 = 0x00030a03  #[ 3  10  3]
        else:
            raise RuntimeError("Incorrect dx dy configuration")
        self.img_filters.select_filter(1)
        self.f2D.start()
        return self.filter2D(src, dst)

    def Laplacian(self, src, ddepth, dst, ksize):
        if ksize == 5:
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if self.filter2D_5Type != 4:
                self.filter2D_5Type = 4  # "Laplacian_5"
                self.f2D_5.par_V = bytes([ \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #4,   -8,   -24,  -8,   4,

                0x04, 0xf8, 0xe8, 0xf8, 0x04, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                0,0,0]) #fill up to allign with 4
            self.img_filters.select_filter(5)
            self.f2D_5.start()
            return self.filter2D(src, dst)
        else:  #ksize 1 or 3
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if ksize == 1:
                if (self.filter2DType != 4):
                    self.filter2DType = 4  # "Laplacian_1"
                    self.f2D.r1 = 0x00000100  #[ 0  1  0]
                    self.f2D.r2 = 0x0001fc01  #[ 1 -4  1]
                    self.f2D.r3 = 0x00000100  #[ 0  1  0]
            elif ksize == 3:
                if (self.filter2DType != 5):
                    self.filter2DType = 5  # "Laplacian_3"
                    self.f2D.r1 = 0x00020002  #[ 2  0  2]
                    self.f2D.r2 = 0x0000f800  #[ 0 -8  0]
                    self.f2D.r3 = 0x00020002  #[ 2  0  2]
            self.img_filters.select_filter(1)
            self.f2D.start()
            return self.filter2D(src, dst)

    def blur(self, src, ksize, dst):
        self.f2D_f.rows = src.shape[0]
        self.f2D_f.columns = src.shape[1]
        if (self.filter2DfType != 0):
            self.filter2DfType = 0  #blur
            mean = self.floatToFixed(1 / 9, cv2pynqDriverFilter2D_f.K_FP_W,
                                     cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r11 = mean
            self.f2D_f.r12 = mean
            self.f2D_f.r13 = mean
            self.f2D_f.r21 = mean
            self.f2D_f.r22 = mean
            self.f2D_f.r23 = mean
            self.f2D_f.r31 = mean
            self.f2D_f.r32 = mean
            self.f2D_f.r33 = mean
        self.img_filters.select_filter(2)
        self.f2D_f.start()
        return self.filter2D(src, dst)

    def GaussianBlur(self, src, ksize, sigmaX, sigmaY, dst):
        self.f2D_f.rows = src.shape[0]
        self.f2D_f.columns = src.shape[1]
        if (self.filter2DfType != 1):
            self.filter2DfType = 1  #GaussianBlur
            if (sigmaX <= 0):
                sigmaX = 0.3 * ((ksize[0] - 1) * 0.5 - 1) + 0.8
            if (sigmaY <= 0):
                sigmaY = sigmaX
            kX = cv2.getGaussianKernel(3, sigmaX, ktype=cv2.CV_32F)  #kernel X
            kY = cv2.getGaussianKernel(3, sigmaY, ktype=cv2.CV_32F)  #kernel Y
            self.f2D_f.r11 = self.floatToFixed(kY[0] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r12 = self.floatToFixed(kY[0] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r13 = self.floatToFixed(kY[0] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r21 = self.floatToFixed(kY[1] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r22 = self.floatToFixed(kY[1] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r23 = self.floatToFixed(kY[1] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r31 = self.floatToFixed(kY[2] * kX[0],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r32 = self.floatToFixed(kY[2] * kX[1],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
            self.f2D_f.r33 = self.floatToFixed(kY[2] * kX[2],
                                               cv2pynqDriverFilter2D_f.K_FP_W,
                                               cv2pynqDriverFilter2D_f.K_FP_F)
        self.img_filters.select_filter(2)
        self.f2D_f.start()
        return self.filter2D(src, dst)

    def erode(self, src, kernel, dst, iterations, mode):
        self.img_filters.select_filter(3)
        return self.erodeDilateKernel(src, kernel, dst, iterations, mode,
                                      self.erodeIP)

    def dilate(self, src, kernel, dst, iterations, mode):
        self.img_filters.select_filter(4)
        return self.erodeDilateKernel(src, kernel, dst, iterations, mode,
                                      self.dilateIP)

    def Canny(self, src, threshold1, threshold2, dst):
        self.img_filters.select_filter(0)
        self.CannyIP.rows = src.shape[0]
        self.CannyIP.columns = src.shape[1]
        self.CannyIP.threshold1 = threshold1
        self.CannyIP.threshold2 = threshold2
        self.CannyIP.start()
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst

        self.cmaBuffer1.nbytes = src.nbytes
        self.dmaIn.transfer(self.cmaBuffer1)
        if hasattr(src, 'physical_address'):
            self.dmaOut.transfer(src)
        else:
            self.cmaBuffer0.nbytes = src.nbytes
            self.copyNto(self.cmaBuffer0, src, src.nbytes)
            self.dmaOut.transfer(self.cmaBuffer0)
        self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        return ret

    def filter2D(self, src, dst):
        if dst is None:
            self.cmaBuffer1.nbytes = src.nbytes
        elif hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
        if hasattr(src, 'physical_address'):
            self.dmaIn.transfer(self.cmaBuffer1)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
        else:  #pipeline the copy to contiguous memory and filter calculation in hardware
            if src.nbytes < 184800:  #440x420
                self.partitions = 1
            elif src.nbytes < 180000:  #600x300
                self.partitions = 2
            elif src.nbytes < 231200:  #680x340
                self.partitions = 4
            else:
                self.partitions = 8
            self.cmaBuffer1.nbytes = src.nbytes
            self.dmaIn.transfer(self.cmaBuffer1)
            chunks_len = int(src.nbytes / (self.partitions))
            self.cmaBuffer0.nbytes = chunks_len
            self.cmaBuffer2.nbytes = chunks_len
            #self.copyNto(src,self.cmaBuffer0,chunks_len)
            self.copyNto(self.cmaBuffer0, src, chunks_len)
            for i in range(1, self.partitions):
                if i % 2 == 1:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer0)
                    #self.copyNtoOff(src ,self.cmaBuffer2,chunks_len, i*chunks_len, 0)
                    self.copyNtoOff(self.cmaBuffer2, src, chunks_len, 0,
                                    i * chunks_len)
                else:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer2)
                    #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len,  i*chunks_len, 0)
                    self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0,
                                    i * chunks_len)
            while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                pass
            self.dmaOut.transfer(self.cmaBuffer2)
            rest = src.nbytes % self.partitions
            if rest > 0:  #cleanup any remaining data and send it to HW
                #self.copyNtoOff(src ,self.cmaBuffer0,chunks_len, self.partitions*chunks_len, 0)
                self.copyNtoOff(self.cmaBuffer0, src, chunks_len, 0,
                                self.partitions * chunks_len)
                while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                    pass
                self.dmaOut.transfer(self.cmaBuffer0)
                rest -= chunks_len
            self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        return ret

    def floatToFixed(self, f, total_bits, fract_bits):
        """convert float f to a signed fixed point with #total_bits and #frac_bits after the point"""
        fix = int((abs(f) * (1 << fract_bits)))
        if (f < 0):
            fix += 1 << total_bits - 1
        return fix

    def erodeDilateKernel(self, src, kernel, dst, iterations, mode, filter):
        filter.mode = mode
        filter.rows = src.shape[0]
        filter.columns = src.shape[1]
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            filter.start()
            if iterations > 1:
                self.dmaIn.transfer(self.cmaBuffer1)
            else:
                self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            self.cmaBuffer2.nbytes = src.nbytes  #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8)
            for i in range(2, iterations + 1):
                filter.start()
                if i % 2 == 0:
                    self.dmaIn.transfer(self.cmaBuffer2)
                    if i != iterations:  #avoid copy after last iteration
                        self.dmaOut.transfer(self.cmaBuffer1)
                    else:
                        self.dmaOut.transfer(dst)
                else:
                    self.dmaIn.transfer(self.cmaBuffer1)
                    if i != iterations:
                        self.dmaOut.transfer(self.cmaBuffer2)
                    else:
                        self.dmaOut.transfer(dst)
                self.dmaIn.wait()
            return dst
        self.cmaBuffer0.nbytes = src.nbytes
        self.cmaBuffer1.nbytes = src.nbytes
        filter.start()
        self.dmaIn.transfer(self.cmaBuffer1)
        if hasattr(src, 'physical_address'):
            self.dmaOut.transfer(src)
        else:
            self.copyNto(self.cmaBuffer0, src,
                         src.nbytes)  #np.copyto(srcBuffer,src)
            self.dmaOut.transfer(self.cmaBuffer0)
        self.dmaIn.wait()
        self.cmaBuffer2.nbytes = src.nbytes  #buffer = self.xlnk.cma_array(src.shape, dtype=np.uint8)
        for i in range(2, iterations + 1):
            filter.start()
            if i % 2 == 0:
                self.dmaIn.transfer(self.cmaBuffer2)
                self.dmaOut.transfer(self.cmaBuffer1)
            else:
                self.dmaIn.transfer(self.cmaBuffer1)
                self.dmaOut.transfer(self.cmaBuffer2)
            self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        if iterations % 2 == 1:
            self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        else:
            self.copyNto(ret, self.cmaBuffer2, ret.nbytes)
        return ret

    '''def cornerHarris(self, src, k, dst):
        self.img_filters.select_filter(5)
        self.cornerHarrisIP.rows = src.shape[0]
        self.cornerHarrisIP.columns = src.shape[1]
        self.cornerHarrisIP.start()
        if hasattr(src, 'physical_address') and hasattr(dst, 'physical_address') and (dst.nbytes == src.nbytes*4):    
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
        
        self.cmaBuffer2.nbytes = src.nbytes*4
        self.dmaIn.transfer(self.cmaBuffer2)
        if hasattr(src, 'physical_address') :
            self.dmaOut.transfer(src)        
        else:
            self.cmaBuffer0.nbytes = src.nbytes
            self.copyNto(self.cmaBuffer0,src,src.nbytes)
            self.dmaOut.transfer(self.cmaBuffer0)        
        self.dmaIn.wait()
        ret = np.ndarray(src.shape,np.float32)
        self.copyNto(ret,self.cmaBuffer2,ret.nbytes)
        return ret'''

    def copyNto(self, dst, src, N):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        self.ffi.memmove(dstPtr, srcPtr, N)

    def copyNtoOff(self, dst, src, N, dstOffset, srcOffset):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        dstPtr += dstOffset
        srcPtr += srcOffset
        self.ffi.memmove(dstPtr, srcPtr, N)

    class ContiguousArrayCv2pynq(ContiguousArray):
        def init(self, cmaArray):
            self._nbytes = cmaArray.nbytes
            self.physical_address = cmaArray.physical_address
            self.cacheable = cmaArray.cacheable

        # overwrite access to nbytes with own function
        @property
        def nbytes(self):
            return self._nbytes

        @nbytes.setter
        def nbytes(self, value):
            self._nbytes = value
コード例 #5
0
class cv2pynq():
    MAX_WIDTH = 1920
    MAX_HEIGHT = 1080

    def __init__(self, load_overlay=True):
        #self.bitstream_name = None
        self.bitstream_name = "opencv.bit"
        self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR,
                                           self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.img_filters = self.ol.image_filters
        self.dmaOut = self.img_filters.axi_dma_0.sendchannel
        self.dmaIn = self.img_filters.axi_dma_0.recvchannel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()
        self.filter2DType = -1  # filter types: SobelX=0, SobelY=1, ScharrX=2, ScharrY=3, Laplacian1=4, Laplacian3=5
        self.filter2D_5Type = -1  # filter types: SobelX=0, SobelY=1,                     Laplacian5=4
        self.f2D = self.img_filters.filter2D_hls_0
        self.f2D.reset()
        self.f2D_5 = self.img_filters.filter2D_hls_5_0
        self.f2D_5.reset()

    def close(self):
        self.dmaOut.stop()
        self.dmaIn.stop()

    def Sobel(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if (dx == 1) and (dy == 0):
                if self.filter2DType != 0:
                    self.filter2DType = 0
                    self.f2D.r1 = 0x000100ff  #[-1  0  1]
                    self.f2D.r2 = 0x000200fe  #[-2  0  2]
                    self.f2D.r3 = 0x000100ff  #[-1  0  1]
            elif (dx == 0) and (dy == 1):
                if self.filter2DType != 1:
                    self.filter2DType = 1
                    self.f2D.r1 = 0x00fffeff  #[-1 -2 -1]
                    self.f2D.r2 = 0x00000000  #[ 0  0  0]
                    self.f2D.r3 = 0x00010201  #[ 1  2  1]
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(0)
            self.f2D.start()
            return self.filter2D(src, dst)
        else:  #ksize == 5
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if (dx == 1) and (dy == 0):
                if self.filter2D_5Type != 0:
                    self.filter2D_5Type = 0
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-6,  -12,  0,    12,   6,

                    0xfa, 0xf4, 0x00, 0x0c, 0x06, \
                    #-4,  -8,   0,    8,    4,

                    0xfc, 0xf8, 0x00, 0x08, 0x04, \
                    #-1,  -2,   0,    2,    1,

                    0xff, 0xfe, 0x00, 0x02, 0x01, \
                    0,0,0]) #fill up to allign with 4
            elif (dx == 0) and (dy == 1):
                if self.filter2D_5Type != 1:
                    self.filter2D_5Type = 1
                    self.f2D_5.par_V = bytes([ \
                    #-1,  -4,   -6,   -4,   -1,

                    0xff, 0xfc, 0xfa, 0xfc, 0xff, \
                    #-2,  -8,   -12,  -8,   -2,

                    0xfe, 0xf8, 0xf4, 0xf8, 0xfe, \
                    # 0,  0,    0,    0,    0,

                    0x00, 0x00, 0x00, 0x00, 0x00, \
                    # 2,  8,    12,   8,    2,

                    0x02, 0x08, 0x0c, 0x08, 0x02, \
                    # 1,  4,    6,    4,    1,

                    0x01, 0x04, 0x06, 0x04, 0x01, \
                    0,0,0]) #fill up to allign with 4
            else:
                raise RuntimeError("Incorrect dx dy configuration")
            self.img_filters.select_filter(1)
            self.f2D_5.start()
            return self.filter2D(src, dst)

    def Laplacian(self, src, ddepth, dst, ksize):
        if ksize == 5:
            self.f2D_5.rows = src.shape[0]
            self.f2D_5.columns = src.shape[1]
            if self.filter2D_5Type != 4:
                self.filter2D_5Type = 4  # "Laplacian_5"
                self.f2D_5.par_V = bytes([ \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #4,   -8,   -24,  -8,   4,

                0x04, 0xf8, 0xe8, 0xf8, 0x04, \
                #4,   0,    -8,   0,    4,

                0x04, 0x00, 0xf8, 0x00, 0x04, \
                #2,   4,    4,    4,    2,

                0x02, 0x04, 0x04, 0x04, 0x02, \
                0,0,0]) #fill up to allign with 4
            self.img_filters.select_filter(1)
            self.f2D_5.start()
            return self.filter2D(src, dst)
        else:  #ksize 1 or 3
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            if ksize == 1:
                if (self.filter2DType != 4):
                    self.filter2DType = 4  # "Laplacian_1"
                    self.f2D.r1 = 0x00000100  #[ 0  1  0]
                    self.f2D.r2 = 0x0001fc01  #[ 1 -4  1]
                    self.f2D.r3 = 0x00000100  #[ 0  1  0]
            elif ksize == 3:
                if (self.filter2DType != 5):
                    self.filter2DType = 5  # "Laplacian_3"
                    self.f2D.r1 = 0x00020002  #[ 2  0  2]
                    self.f2D.r2 = 0x0000f800  #[ 0 -8  0]
                    self.f2D.r3 = 0x00020002  #[ 2  0  2]
            self.img_filters.select_filter(0)
            self.f2D.start()
            return self.filter2D(src, dst)

    def filter2D(self, src, dst):
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
コード例 #6
0
class cv2PL():
    MAX_WIDTH = 1920
    MAX_HEIGHT = 1080

    def __init__(self, load_overlay=True):
        self.bitstream_name = "base.bit"
        self.bitstream_path = os.path.join(CV2PYNQ_BIT_DIR,
                                           self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.xlnk = Xlnk()
        self.partitions = 10  # Split the CMA into partitions for pipelined transfer
        self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions
        self.listOfcma = [
            self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions),
                                       self.MAX_WIDTH),
                                dtype=np.uint8) for i in range(self.partitions)
        ]
        self.img_filters = self.ol.img_process
        self.dmaOut = self.img_filters.axi_dma_0.sendchannel  # The memory to stream channel
        self.dmaIn = self.img_filters.axi_dma_0.recvchannel  # The stream to memory channel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()

        self.CannyIP = self.img_filters.canny_edge_0
        self.CannyIP.reset()
        self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer0.init(self.cmaBuffer_0)
        self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer1.init(self.cmaBuffer_1)
        self.cmaBuffer_2 = self.xlnk.cma_array(
            shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH),
            dtype=np.uint8)  # *4 for CornerHarris return
        self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer2.init(self.cmaBuffer_2)

    def close(self):
        #self.dmaOut.stop()
        #self.dmaIn.stop()
        self.cmaBuffer_0.close()
        self.cmaBuffer_1.close()
        self.cmaBuffer_2.close()
        for cma in self.listOfcma:
            cma.close()

    def Canny(self, src, threshold1, threshold2, dst):
        self.CannyIP.rows = src.shape[0]
        self.CannyIP.columns = src.shape[1]
        self.CannyIP.threshold1 = threshold1
        self.CannyIP.threshold2 = threshold2
        self.CannyIP.start()
        if hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst

    def floatToFixed(self, f, total_bits, fract_bits):
        """convert float f to a signed fixed point with #total_bits and #frac_bits after the point"""
        fix = int((abs(f) * (1 << fract_bits)))
        if (f < 0):
            fix += 1 << total_bits - 1
        return fix

    def copyNto(self, dst, src, N):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        self.ffi.memmove(dstPtr, srcPtr, N)

    def copyNtoOff(self, dst, src, N, dstOffset, srcOffset):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        dstPtr += dstOffset
        srcPtr += srcOffset
        self.ffi.memmove(dstPtr, srcPtr, N)

    class ContiguousArrayCv2pynq(ContiguousArray):
        def init(self, cmaArray):
            self._nbytes = cmaArray.nbytes
            self.physical_address = cmaArray.physical_address
            self.cacheable = cmaArray.cacheable

        # overwrite access to nbytes with own function
        @property
        def nbytes(self):
            return self._nbytes

        @nbytes.setter
        def nbytes(self, value):
            self._nbytes = value
コード例 #7
0
class cv2pynq():
    MAX_WIDTH = 800
    MAX_HEIGHT = 600

    def __init__(self, load_overlay=True):
        self.bitstream_name = None
        self.bitstream_name = "imgfilter.bit"
        self.bitstream_path = os.path.join(self.bitstream_name)
        self.ol = Overlay(self.bitstream_path)
        self.ol.download()
        self.ol.reset()
        self.xlnk = Xlnk()
        self.partitions = 10  #split the cma into partitions for pipelined transfer
        self.cmaPartitionLen = self.MAX_HEIGHT * self.MAX_WIDTH / self.partitions
        self.listOfcma = [
            self.xlnk.cma_array(shape=(int(self.MAX_HEIGHT / self.partitions),
                                       self.MAX_WIDTH),
                                dtype=np.uint8) for i in range(self.partitions)
        ]
        self.filter2d = self.ol
        self.dmaOut = self.filter2d.axi_dma_0.sendchannel
        self.dmaIn = self.filter2d.axi_dma_0.recvchannel
        self.dmaOut.stop()
        self.dmaIn.stop()
        self.dmaIn.start()
        self.dmaOut.start()
        self.filter2DType = -1  # filter types: SobelX=0
        self.ffi = FFI()
        self.f2D = self.filter2d.filter2D_hls_0
        self.f2D.reset()
        self.cmaBuffer_0 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer0 = self.cmaBuffer_0.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer0.init(self.cmaBuffer_0)
        self.cmaBuffer_1 = self.xlnk.cma_array(shape=(self.MAX_HEIGHT,
                                                      self.MAX_WIDTH),
                                               dtype=np.uint8)
        self.cmaBuffer1 = self.cmaBuffer_1.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer1.init(self.cmaBuffer_1)
        self.cmaBuffer_2 = self.xlnk.cma_array(
            shape=(self.MAX_HEIGHT * 4, self.MAX_WIDTH),
            dtype=np.uint8)  # *4 for CornerHarris return
        self.cmaBuffer2 = self.cmaBuffer_2.view(self.ContiguousArrayCv2pynq)
        self.cmaBuffer2.init(self.cmaBuffer_2)

    def close(self):
        self.cmaBuffer_0.close()
        self.cmaBuffer_1.close()
        self.cmaBuffer_2.close()
        for cma in self.listOfcma:
            cma.close()

    def copyNto(self, dst, src, N):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        self.ffi.memmove(dstPtr, srcPtr, N)

    def copyNtoOff(self, dst, src, N, dstOffset, srcOffset):
        dstPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(dst))
        srcPtr = self.ffi.cast("uint8_t *", self.ffi.from_buffer(src))
        dstPtr += dstOffset
        srcPtr += srcOffset
        self.ffi.memmove(dstPtr, srcPtr, N)

    def filter2D(self, src, dst):
        if dst is None:
            self.cmaBuffer1.nbytes = src.nbytes
        elif hasattr(src, 'physical_address') and hasattr(
                dst, 'physical_address'):
            self.dmaIn.transfer(dst)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
            return dst
        if hasattr(src, 'physical_address'):
            self.dmaIn.transfer(self.cmaBuffer1)
            self.dmaOut.transfer(src)
            self.dmaIn.wait()
        else:  #pipeline the copy to contiguous memory and filter calculation in hardware
            if src.nbytes < 184800:  #440x420
                self.partitions = 1
            elif src.nbytes < 180000:  #600x300
                self.partitions = 2
            elif src.nbytes < 231200:  #680x340
                self.partitions = 4
            else:
                self.partitions = 8
            self.cmaBuffer1.nbytes = src.nbytes
            self.dmaIn.transfer(self.cmaBuffer1)
            chunks_len = int(src.nbytes / (self.partitions))
            self.cmaBuffer0.nbytes = chunks_len
            self.cmaBuffer2.nbytes = chunks_len
            self.copyNto(src, self.cmaBuffer0, chunks_len)
            for i in range(1, self.partitions):
                if i % 2 == 1:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer0)
                    self.copyNtoOff(src, self.cmaBuffer2, chunks_len,
                                    i * chunks_len, 0)
                else:
                    while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                        pass
                    self.dmaOut.transfer(self.cmaBuffer2)
                    self.copyNtoOff(src, self.cmaBuffer0, chunks_len,
                                    i * chunks_len, 0)
            while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                pass
            self.dmaOut.transfer(self.cmaBuffer2)
            rest = src.nbytes % self.partitions
            if rest != 0:  #cleanup any remaining data and send it to HW
                self.copyNtoOff(src, self.cmaBuffer0, chunks_len,
                                self.partitions * chunks_len, 0)
                while not self.dmaOut.idle and not self.dmaOut._first_transfer:
                    pass
                self.dmaOut.transfer(self.cmaBuffer0)
            self.dmaIn.wait()
        ret = np.ndarray(src.shape, src.dtype)
        self.copyNto(ret, self.cmaBuffer1, ret.nbytes)
        return ret

    class ContiguousArrayCv2pynq(ContiguousArray):
        def init(self, cmaArray):
            self._nbytes = cmaArray.nbytes
            self.physical_address = cmaArray.physical_address
            self.cacheable = cmaArray.cacheable

        # overwrite access to nbytes with own function
        @property
        def nbytes(self):
            return self._nbytes

        @nbytes.setter
        def nbytes(self, value):
            self._nbytes = value

    def Sobel(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            self.filter2DType = 0
            self.f2D.rows = src.shape[0]
            self.f2D.columns = src.shape[1]
            self.f2D.channels = 1
            self.f2D.r1 = 0x000100ff  #[-1  0  1]
            self.f2D.r2 = 0x000200fe  #[-2  0  2]
            self.f2D.r3 = 0x000100ff  #[-1  0  1]
            self.f2D.start()
            return self.filter2D(src, dst)

    def Sobel1(self, src, ddepth, dx, dy, dst, ksize):
        if (ksize == 3):
            if self.filter2DType != 1:
                self.filter2DType = 1
                self.f2D.rows = src.shape[0]
                self.f2D.columns = src.shape[1]
                self.f2D.channels = 1
                self.f2D.r1 = 0x00fffeff  #[-1 -2 -1]
                self.f2D.r2 = 0x00000000  #[ 0  0  0]
                self.f2D.r3 = 0x00010201  #[ 1  2  1]
                self.f2D.start()
                return self.filter2D(src, dst)