dithering

Hi,

I’m trying to apply some dithering algo to an image with that code, but the set_pixel function doesn’t seem to have any effect.

# Hello World Example
#
# Welcome to the OpenMV IDE! Click on the green run arrow button below to run the script!

import sensor, image, time, lcd

sensor.reset()                      # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)   # Set frame size to QVGA (320x240)
sensor.skip_frames(10)              # Wait for settings take effect.
clock = time.clock()                # Create a clock object to track the FPS.
lcd.init()

kernel_2x2 = [[0, 2], [3, 1]]

def coef(kernel, i, j):
    return 255 * (1 + kernel[i][j]) / (1 + len(kernel) * len(kernel[0]))

def ordered_dithering(img, kernel):
    height_img, width_img =(img.height(), img.width())
    height_kernel, width_kernel = (len(kernel), len(kernel[0]))
    for x in range(width_img, width_kernel):
        for y in range(height_img, height_kernel):
            for i in range(width_kernel):
                for j in range(height_kernel):
                    pixel = 255 if img.get_pixel(x + i, y + j) < coef(kernel, i, j) else 0
                    img.set_pixel(x + i, y + j, pixel)
    img.draw_string(0, 0, "h: %d, w: %d" % (height_img, width_img))
    img.draw_string(0, 10, "h: %d, w: %d" % (height_kernel, width_kernel))

    return img

while(True):
    clock.tick()                    # Update the FPS clock.
    img = sensor.snapshot()         # Take a picture and return the image.
    bw = ordered_dithering(img, kernel_2x2)
    lcd.display(bw)
    print(clock.fps())              # Note: OpenMV Cam runs about half as fast when connected
                                    # to the IDE. The FPS should increase once disconnected.

On the lcd, I can see the text, but pixel values are not changing. Do I miss something ?

Thanks

img.set_pixel(x, y, 255)

This should work, just tested it. Um, it does clip drawing if you are off screen. Can you check that?

No, it doesn’t help.
I reduced the size of the code to try to narrow down the root cause, but it doesn’t help

import sensor, lcd

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames()
lcd.init()

while(True):
    img = sensor.snapshot()         # Take a picture and return the image.
    for x in range(100, 2):
        for y in range(100, 2):
            img.set_pixel(x, y, 255)
    img.draw_line((0, 0, 10, 10))
    lcd.display(img)

With that code, I don’t see the dots on neither the LCD nor the preview in the IDE.
I only see the white diagonal on the preview in the IDE, not on the LCD.

Any clue ?

Mmm, looks like your resolution is wrong. You need to use QQVGA2. Otherwise the image gets cropped to just the center of it.

http://docs.openmv.io/library/omv.sensor.html#sensor.sensor.QQVGA2

BTW, did you update the firmware?

I prefer QQVGA because it keeps a correct aspect ratio when rotating the LCD in landscape mode.

Using QQVGA2, I can see the white diagonal on the LCD too, but I still don’t see the dots set with set_pixel.

I have a M4 OV7725 with firmware 2.3.0 (IDE 1.5.2)

Is there a reason py_image_draw_line is using imlib_draw_line, but py_image_set_pixel is reimplementing part of imlib_set_pixel directly using the IM_* defines ? (maybe to handle the p arg?)

Yes:

range(start, stop[, step])

silly me … :blush:
It works. As for the diagonal not being visible on the lcd with QQVGA, it’s only due to the crop to fit the screen.

Thanks