Ya plein de choses qui clochent.
Déjà tu présentes ton code sans le mettre entre <code></code>, du coup c’est pas glop 
Ensuite ta condition de vérification ne sera jamais vérifiée (im1 ne peux pas être casté en int).
D’ailleurs si ça chie, ça lèvera une exception en toute logique, donc autant faire un try catch (je connais pas la syntaxe exacte, je ne suis pas un pythonier).
p=im1.getpixel((x,y))
if p>=N:
Pose un problème, c’est que p sera de type tuple, et tu veux le comparer à un entier. En fait en imagerie numérique, il y a plusieurs métriques pour évaluer la valeur de gris d’un pixel, tu peux prendre le max des 3 composantes, ou alors la moyenne arithmétique, géométrique ou harmonique (moins courant), faire des moyennes pondérées, etc…
Pour accéder au rouge c’est p[0] du coup, p[1] pour le vert et p[2] pour le bleu, tu peux aussi faire un:
prouge, pvert, pbleu = im1.getpixel(x,y)
J’imagine, pour avoir accès aux composantes directement et plus lisiblement.
Ensuite un dernier problème, c’est que im2 n’est pas initialisée, tu peux le faire avec un :
im2 = Images.new("RGB", im1.size)
J’ai mis RGB parce que ce sont les notations que tu as adopté, mais ça serait mieux de faire du niveau de gris à la place ( "L" à la place de "RGB"), mais du coup il faudrait aussi remplacer tes putpixels (r,g,b) par putpixel(valeur).
Et voilà, avec ton code corrigé, je peux obtenir :

Addendum: Et accessoirement, le jpg c’est pas le format idéal je pense pour sauver le résultat, essaye de passer en gif ou en png.