• Jason

    @ccc Hmmmm, I thought PNG is not compressed so it would be safe already.

    posted in Pythonista read more
  • Jason

    @cvp It worked! Thanks!

    posted in Pythonista read more
  • Jason

    Hi all.
    I crafted a little script to do stegnography in python. Here is the code: https://github.com/Xunius/py_stegnography.

    The 3 files in the repo:

    • steg.py: this does the core computations, also works as a CLI command.
    • steg_ui.pyui: the pythonista ui design.
    • steg_pythonista.py: script for use in pythonista.

    In the pythonista ui, you are presented with an image selection button, from which you select a "carrier image" from camera roll.

    The textview widget below shows the message you intend to hide, or the message read from the "carrier image". So if it's empty, it will try to read a hidden message. If non-empty, it will hide the message into the chosen image, and create a new png version of it.

    This is achieved by converting the message into binary, and put that binary stream into the last bits in the color channels in the pixels. If the change is restricted to the last couple of bits, it is invisible to the eyes. The reading process is doing the opposite.

    Optionally one can encrypt the message first. But it doesn't seem to work inside pythonista, the encryption part is throwing error at me.

    Another issue I noticed is it often freezes after photos.pick_image(). Any idea why?

    Improvements are welcome!

    posted in Pythonista read more
  • Jason

    Hi all. I’m sharing a little script I crafted that turns an input image into gray scale, and then makes a spiral to approximate it.

    When run, the script prompts you to choose an image to process or use the Lena demo.

    ''' convert image to a big spiral
    '''
    
    dr1=3.0  # delta radius for inner spiral
    dr2=3    # delta radius for outter spiral
    lseg=4   # length of spiral segment treated as a line
    nlayers=4 # NO. of layers to segment gray scale img
    sigma=3  # radius for Gaussian blur
    
    
    
    #--------Import modules-------------------------
    import numpy as np
    from PIL import Image
    from PIL import ImageFilter
    import matplotlib.pyplot as plt
    import dialogs
    import photos
    
    #-------------Main---------------------------------
    if __name__=='__main__':
        
        #----------Read image-----
        i = dialogs.alert('Image', '', 'Demo Image', 'Select from Photos')
        if i == 1:
            img = Image.open('test:Lenna')
        else:
            img = photos.pick_image()
            
        img=img.convert('L')
    
        # resize
        newsize=(300, int(float(img.size[1])/img.size[0]*300))
        img=img.resize(newsize,Image.ANTIALIAS)
        print('Image size: %s' %str(img.size))
    
        # blur
        img=img.filter(ImageFilter.GaussianBlur(sigma))
    
        # convert to array
        img=np.array(img)
        img=img[::-1,:]
    
        # thresholding
        layers=np.linspace(np.min(img),np.max(img),nlayers+1)
        img_layers=np.zeros(img.shape)
        ii=1
        for z1,z2 in zip(layers[:-1],layers[1:]):
            img_layers=np.where((img>=z1) & (img<z2),ii,img_layers)
            ii+=1
        img_layers=img_layers.max()-img_layers+1
    
        # get diagonal length
        size=img.shape # ny,nx
        diag=np.sqrt(size[0]**2/4+size[1]**2/4)
    
        figure=plt.figure(figsize=(12,10),dpi=100)
        ax=figure.add_subplot(111)
    
        # create spiral
        rii=1.0
        line=np.zeros(img.shape)
        nc=0
        while True:
            if nc==0:
                rii2=rii+dr1
            elif nc<0:
                rii=rii2
                rii2=rii+dr1
            else:
                rii=rii2
                rii2=rii+dr2
    
            print('r = %.1f' %rii)
            nii=max(64,2*np.pi*rii//lseg)
            tii=np.linspace(0,2*np.pi,nii)
            riis=np.linspace(rii,rii2,nii)
            xii=riis*np.cos(tii)
            yii=riis*np.sin(tii)
    
            if np.all(riis>=diag):
                break
    
            # get indices
            xidx=np.around(xii,0).astype('int')+size[1]//2
            yidx=np.around(yii,0).astype('int')+size[0]//2
            idx=[jj for jj in range(len(yidx)) if xidx[jj]>=0 and yidx[jj]>=0\
                    and xidx[jj]<=size[1]-1 and yidx[jj]<=size[0]-1]
            xidx=xidx[idx]
            yidx=yidx[idx]
    
            # skip diagonal jumps
            if len(yidx)>0 and yidx[0]*yidx[-1]<0:
                continue
            xii=xii[idx]
            yii=yii[idx]
    
            # pick line width from image
            lw=img_layers[yidx,xidx]
    
            # add random perturbation
            lwran=np.random.random(lw.shape)-0.5
            lw=lw+lwran
    
            # randomize color
            colorjj=np.random.randint(0,60)*np.ones(3)/float(255)
    
            for jj in range(len(xii)-1):
    
                # smooth line widths
                lwjjs=lw[max(0,jj-3):min(len(lw),jj+3)]
                if jj==0 and nc>0:
                    lwjjs=np.r_[lwjjs_old,lwjjs]
    
                wjj=np.ones(len(lwjjs))
                wjj=wjj/len(wjj)
                lwjj=np.dot(lwjjs,wjj)
    
                ax.plot([xii[jj], xii[jj+1]],
                        [yii[jj], yii[jj+1]],
                        color=colorjj,
                        linewidth=lwjj)
    
                if jj==len(xii)-2:
                    lwjjs_old=lwjjs
    
            nc+=1
    
        ax.axis('off')
        #ax.set_facecolor((1.,0.5,0.5))
        ax.set_aspect('equal')
        plt.show()
    
    

    posted in Pythonista read more
  • Jason

    Update myself:

    I've changed the script to load image from within pythonista rather than running as extension so we don't have the resource limitations, and also re-computed the model parameters. Now the script works, although the model itself is far from accurate.

    posted in Pythonista read more
  • Jason

    Thanks for the reply.

    You are probably right. If I shrink the image size down to about 150 in both dimension it works, but it becomes too small for the detector to actually work at least for now.

    posted in Pythonista read more
  • Jason

    Hi all,

    I'm trying to make a simple pedestrian detection script in numpy and port it to run on my phone. It consists of 2 scipts (hog_pythonista.py and pede_detect_pythonista.py). When using the sample image inside Image like this:

        if not appex.is_running_extension():
            print('Running in Pythonista app, using test image...')
            img=Image.open('test:Mandrill')
        else:
            img=appex.get_image()
    

    It works OK, but if I go into the photo lib and run as extension, it will fail at the function call into hog_pythonista.py. Any idea what's going wrong?

    hog_pythonista.py here: https://github.com/Xunius/HOG_python/blob/master/hog_pythonista.py
    pede_detect_pythonista.py here: https://github.com/Xunius/HOG_python/blob/master/pede_detect_pythonista.py

    Thanks

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!