Hi,Every one! I had two openmv h7 board. one(A board) be fixed left side ,the other one(B board) be fixed right,but how to compare the two image similiarity and transfer image A board image to B board,B board received A board iamge Usart information ,then converted them to Image information? Thanks!
Then use the image similarly method to compare the two.
@ kwagyeman ,Thanks! That is what I wanted. But I found ,at QVGA mode,it only 4 FPS. I only get the QVGA mode special point value. How to speed up the FPS.Thanks! In follow this code ,I want to transfer img17 to othe board, it only 20 x 16 point.
slave code:
# Image Transfer - As The Remote Device
#
# This script is made to pair with another OpenMV Cam running "image_transfer_raw_as_the_controller_device.py"
#
# This script shows off how to transfer the frame buffer from one OpenMV Cam to another.
import image, network, rpc, sensor, struct
import utime
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to be controlled over CAN, I2C, SPI, UART, or WIFI.
################################################################
# Choose the interface you wish to control your OpenMV Cam over.
################################################################
# Uncomment the below line to setup your OpenMV Cam for control over CAN.
#
# * message_id - CAN message to use for data transport on the can bus (11-bit).
# * bit_rate - CAN bit rate.
# * sampling_point - Tseg1/Tseg2 ratio. Typically 75%. (50.0, 62.5, 75.0, 87.5, etc.)
#
# NOTE: Master and slave message ids and can bit rates must match. Connect master can high to slave
# can high and master can low to slave can lo. The can bus must be terminated with 120 ohms.
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=1000000, sampling_point=75.0)
# Uncomment the below line to setup your OpenMV Cam for control over I2C.
#
# * slave_addr - I2C address.
#
# NOTE: Master and slave addresses must match. Connect master scl to slave scl and master sda
# to slave sda. You must use external pull ups. Finally, both devices must share a ground.
#
# interface = rpc.rpc_i2c_slave(slave_addr=0x12)
# Uncomment the below line to setup your OpenMV Cam for control over SPI.
#
# * cs_pin - Slave Select Pin.
# * clk_polarity - Idle clock level (0 or 1).
# * clk_phase - Sample data on the first (0) or second edge (1) of the clock.
#
# NOTE: Master and slave settings much match. Connect CS, SCLK, MOSI, MISO to CS, SCLK, MOSI, MISO.
# Finally, both devices must share a common ground.
#
# interface = rpc.rpc_spi_slave(cs_pin="P3", clk_polarity=1, clk_phase=0)
# Uncomment the below line to setup your OpenMV Cam for control over UART.
#
# * baudrate - Serial Baudrate.
#
# NOTE: Master and slave baud rates must match. Connect master tx to slave rx and master rx to
# slave tx. Finally, both devices must share a common ground.
#
interface = rpc.rpc_uart_slave(baudrate=7500000)
def timeit(f, *args, **kwargs):
func_name = str(f).split(' ')[1]
def new_func(*args, **kwargs):
t = utime.ticks_us()
result = f(*args, **kwargs)
print('execution time: ', utime.ticks_diff(utime.ticks_us(), t), ' us')
return result
return new_func
def img_process(img):
'''
Get Boll Point image
'''
img1 = img.copy(roi = (181,40,40,2), x_scale = 1.0, y_scale = 1.0)
img1_cp = img1.mean_pooled(2,2)
img.draw_image(img1_cp,0,0)
img2 = img.copy(roi = (181,82,40,2), x_scale = 1.0, y_scale = 1.0)
img2_cp = img2.mean_pooled(2,2)
img.draw_image(img2_cp,0,1)
img3 = img.copy(roi = (181,114,40,2),x_scale = 1.0, y_scale = 1.0)
img3_cp = img3.mean_pooled(2,2)
img.draw_image(img3_cp,0,2)
for i in range(1,21):
img4 = img.copy(roi = ((171+(i-1)*3),140,2,2),x_scale = 1.0, y_scale = 1.0)
img4_cp = img4.mean_pool(2,2)
img.draw_image(img4_cp, i-1, 3)
for i in range(1,21):
img5 = img.copy(roi = ((171+(i-1)*3),160,2,2),x_scale = 1.0, y_scale = 1.0)
img5_cp = img5.mean_pooled(2,2)
img.draw_image(img5_cp, (i-1), 4)
for i in range(1,21):
img6 = img.copy(roi = ((161+(i-1)*4),176,2,2),x_scale = 1.0, y_scale = 1.0)
img6_cp = img6.mean_pooled(2,2)
img.draw_image(img6_cp, i-1, 5)
for i in range(1,21):
img7 = img.copy(roi =((161+ (i-1)*4),189, 2,2),x_scale =1.0, y_scale = 1.0)
img7_cp = img7.mean_pooled(2,2)
img.draw_image(img7_cp, i-1, 6)
for i in range(1,21):
img8 = img.copy(roi = ((151 + (i-1)*4),200, 2,3),x_scale =1.0, y_scale = 1.0)
img8_cp = img8.mean_pooled(2,3)
img.draw_image(img8_cp, i-1, 7)
for i in range(1,21):
img9 = img.copy(roi = ((141+ (i-1)*5),208, 2,3),x_scale =1.0, y_scale = 1.0)
img9_cp = img9.mean_pooled(2,3)
img.draw_image(img9_cp, i-1, 8)
for i in range(1,21):
img10 = img.copy(roi = ((131+(i-1)*5),214, 2,4),x_scale =1.0, y_scale = 1.0)
img10_cp = img10.mean_pooled(2,4)
img.draw_image(img10_cp, i-1, 9)
for i in range(1,21):
img11 = img.copy(roi = ((121 +(i-1)*6),220, 2,4),x_scale =1.0, y_scale = 1.0)
img11_cp = img11.mean_pooled(2,4)
img.draw_image(img11_cp, i-1, 10)
for i in range(1,21):
img12 = img.copy(roi = ((111 +(i-1)*6),224,2,5),x_scale =1.0, y_scale = 1.0)
img12_cp = img12.mean_pooled(2,5)
img.draw_image(img12_cp, i-1, 11)
for i in range(1,21):
img13 = img.copy(roi = ((101+ (i-1) * 7),227, 2,5), x_scale = 1.0, y_scale = 1.0)
img13_cp = img13.mean_pooled(2,5)
img.draw_image(img13_cp, i-1, 12)
for i in range(1,21):
img14 = img.copy(roi = ((91 + (i-1) * 7),230, 2, 6),x_scale = 1.0, y_scale = 1.0)
img14_cp = img14.mean_pooled(2,6)
img.draw_image(img14_cp, i-1, 13)
for i in range(1,21):
img15 = img.copy(roi = ((81 + (i-1) *8 ),232, 2, 6),x_scale = 1.0, y_scale = 1.0)
img15_cp = img15.mean_pooled(2,6)
img.draw_image(img15_cp, i-1, 14)
for i in range(1,21):
img16 = img.copy(roi = ((81 + (i-1) * 7),234, 2, 6),x_scale = 1.0, y_scale = 1.0)
img16_cp = img16.mean_pooled(2,6)
img.draw_image(img16_cp , i-1, 15)
img17 = img.copy(roi = (0, 0,20, 16), x_scale = 1.0, y_scale = 1.0)
img.clear()
img.draw_image(img17, 100,100,x_scale = 1.0, y_scale = 1.0) # put image to PyImage
return img17
################################################################
# Call Backs
################################################################
# When called sets the pixformat and framesize, takes a snapshot
# and then returns the frame buffer shape to store the image in.
#
# data is a 4 byte pixformat and 4 byte framesize.
def raw_image_snapshot(data):
pixformat, framesize = struct.unpack("<II", data)
sensor.set_pixformat(pixformat)
sensor.set_framesize(framesize)
img = sensor.snapshot()
pImage = img_process(img)
return struct.pack("<IIII", sensor.width(), sensor.height(), sensor.get_pixformat(), pImage.size())
#return struct.pack("<IIII", 16, 20, sensor.get_pixformat(), pImage.size())
def raw_image_read_cb():
interface.put_bytes(sensor.get_fb().bytearray(), 50) # timeout
# Read data from the frame buffer given a offset and size.
# If data is empty then a transfer is scheduled after the RPC call finishes.
#
# data is a 4 byte size and 4 byte offset.
def raw_image_read(data):
if not len(data):
interface.schedule_callback(raw_image_read_cb)
return bytes()
else:
offset, size = struct.unpack("<II", data)
return memoryview(sensor.get_fb().bytearray())[offset:offset+size]
# Register call backs.
interface.register_callback(raw_image_snapshot)
interface.register_callback(raw_image_read)
# Once all call backs have been registered we can start
# processing remote events. interface.loop() does not return.
interface.loop()
master code:
# Image Transfer - As The Controller Device
#
# This script is made to pair with another OpenMV Cam running "image_transfer_raw_as_the_remote_device.py"
#
# This script shows off how to transfer the frame buffer from one OpenMV Cam to another.
import image, network, omv, rpc, sensor, struct, time
import utime
def timeit(f, *args, **kwargs):
func_name = str(f).split(' ')[1]
def new_func(*args, **kwargs):
t = utime.ticks_us()
result = f(*args, **kwargs)
print('execution time: ', utime.ticks_diff(utime.ticks_us(), t), ' us')
return result
return new_func
# The RPC library above is installed on your OpenMV Cam and provides mutliple classes for
# allowing your OpenMV Cam to control over CAN, I2C, SPI, UART, or WIFI.
##############################################################
# Choose the interface you wish to control an OpenMV Cam over.
##############################################################
# Uncomment the below line to setup your OpenMV Cam for controlling over CAN.
#
# * message_id - CAN message to use for data transport on the can bus (11-bit).
# * bit_rate - CAN bit rate.
# * sampling_point - Tseg1/Tseg2 ratio. Typically 75%. (50.0, 62.5, 75.0, 87.5, etc.)
#
# NOTE: Master and slave message ids and can bit rates must match. Connect master can high to slave
# can high and master can low to slave can lo. The can bus must be terminated with 120 ohms.
#
# interface = rpc.rpc_can_master(message_id=0x7FF, bit_rate=1000000, sampling_point=75.0)
# Uncomment the below line to setup your OpenMV Cam for controlling over I2C.
#
# * slave_addr - I2C address.
# * rate - I2C Bus Clock Frequency.
#
# NOTE: Master and slave addresses must match. Connect master scl to slave scl and master sda
# to slave sda. You must use external pull ups. Finally, both devices must share a ground.
#
# interface = rpc.rpc_i2c_master(slave_addr=0x12, rate=1000000)
# Uncomment the below line to setup your OpenMV Cam for controlling over SPI.
#
# * cs_pin - Slave Select Pin.
# * freq - SPI Bus Clock Frequency
# * clk_polarity - Idle clock level (0 or 1).
# * clk_phase - Sample data on the first (0) or second edge (1) of the clock.
#
# NOTE: Master and slave settings much match. Connect CS, SCLK, MOSI, MISO to CS, SCLK, MOSI, MISO.
# Finally, both devices must share a common ground.
#
# interface = rpc.rpc_spi_master(cs_pin="P3", freq=20000000, clk_polarity=1, clk_phase=0)
# Uncomment the below line to setup your OpenMV Cam for controlling over UART.
#
# * baudrate - Serial Baudrate.
#
# NOTE: Master and slave baud rates must match. Connect master tx to slave rx and master rx to
# slave tx. Finally, both devices must share a common ground.
#
interface = rpc.rpc_uart_master(baudrate=7500000)
##############################################################
# Call Back Handlers
##############################################################
@timeit
def get_frame_buffer_call_back(pixformat, framesize, cutthrough, silent):
if not silent: print("Getting Remote Frame...")
result = interface.call("raw_image_snapshot", struct.pack("<II", pixformat, framesize))
if result is not None:
w, h, pixformat, size = struct.unpack("<IIII", result)
img = image.Image(w, h, pixformat, copy_to_fb=True) # Alloc cleared frame buffer.
if cutthrough:
# Fast cutthrough data transfer with no error checking.
# Before starting the cut through data transfer we need to sync both the master and the
# slave device. On return both devices are in sync.
result = interface.call("raw_image_read")
if result is not None:
# GET BYTES NEEDS TO EXECUTE NEXT IMMEDIATELY WITH LITTLE DELAY NEXT.
# Read all the image data in one very large transfer.
interface.get_bytes(img.bytearray(), 50) # timeout
else:
# Slower data transfer with error checking.
# Transfer 32/8 KB chunks.
chunk_size = (1 << 15) if omv.board_type() == "H7" else (1 << 13)
if not silent: print("Reading %d bytes..." % size)
for i in range(0, size, chunk_size):
ok = False
for j in range(3): # Try up to 3 times.
result = interface.call("raw_image_read", struct.pack("<II", i, chunk_size))
if result is not None:
img.bytearray()[i:i+chunk_size] = result # Write the image data.
if not silent: print("%.2f%%" % ((i * 100) / size))
ok = True
break
if not silent: print("Retrying... %d/2" % (j + 1))
if not ok:
if not silent: print("Error!")
return None
return img
else:
if not silent: print("Failed to get Remote Frame!")
return None
clock = time.clock()
while(True):
clock.tick()
# You may change the pixformat and the framesize of the image transfered from the remote device
# by modifying the below arguments.
#
# When cutthrough is False the image will be transferred through the RPC library with CRC and
# retry protection on all data moved. For faster data transfer set cutthrough to True so that
# get_bytes() and put_bytes() are called after an RPC call completes to transfer data
# more quicly from one image buffer to another. Note: This works because once an RPC call
# completes successfully both the master and slave devices are synchronized completely.
#
img = get_frame_buffer_call_back(sensor.RGB565, sensor.QVGA, cutthrough=True, silent=True)
if img is not None:
pass # You can process the image here.
#img.draw_image(img, 100,100,x_scale = 1.0, y_scale = 1.0)
print(clock.fps())
Use SPI. There’s no magic here. Calculate the bitrate you need and you’ll see that you need to make it in a very high MHZ number if you want to move a raw image at a particular FPS.
Otherwise, crop the image and make it smaller.