opencv face detection CAPTCHA - python-2.7

please im working on using face detection as a captcha system. how do i make the system print an error message if a face is not detected in the webcam. and also make the number of attempts to detect a face is 3 such that after 3 attempts it closes in python
from Tkinter import *
import numpy as np
import cv2
import Tkinter as tk
import tkMessageBox
import random
import webbrowser
def Request_1(event):
#messagebox gestures
trials = 0
while trials<3:
tkMessageBox.showinfo("ATTENTION!!!", "press letter a when you see the yellow box on your nose")
#this aspect is to generate random requests for the captcha system
detector2= cv2.CascadeClassifier('haarcascade_mcs_nose.xml')
cap = cv2.VideoCapture(0)
access = True
while(access):
#reads the image
ret2, img2 = cap.read()
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Detect faces in the image . the image is read and convertedd to grayscale
faces2 = detector2.detectMultiScale(gray2, 1.3, 5)
if(len(faces2)!=0):
for (x,y,w,h) in faces2:
cv2.rectangle(img2,(x,y),(x+w,y+h),(0,255,255),1)
cv2.imshow('frame',img2)
break
if cv2.waitKey(1) & 0xFF == ord('a'):
#grant access to webpage
cap.release()
cv2.destroyAllWindows()
new=2
url="file:///C:/Users/jayrush/Desktop/lmarku/index.html";
webbrowser.open(url, new=new);
break
if(len(faces2)==0):
trials=trials+1
print("Access Denied")
#defining the interface of the captcha
#INTERFACE
root = Tk()
root.title("Face Detection CAPTCHA")
root.geometry("350x50")
bottomFrame = Frame(root)
bottomFrame.pack()
button_1 = Button(bottomFrame, fg="blue", text="I am not a robot")
button_1.bind("<Button-1>", Request_1)
button_1.pack()
status = Label(root, fg="red", text="Starting captcha...", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()

Related

Python executable hangs with plt.show()

I am creating a GUI application (EXE) in Python 2.7 on Win 10 platform.
The application is supposed to plot a graph (using matplotlib) with user provided parameters. When the user changes the values and presses the plot button again, new graph should be plotted on the same figure retaining the previous curves for ease of comparison (also a requirement).
I had to use plt.show() at the end of the script to show the graph when running the exe file of my program.
Problem: Application freezes and crashes when the plot button is pressed the second time. For the first time, everything goes fine and the graph is displayed.
Solutions tried:
Going thru so many threads, I tried following solutions without luck:
Used plt.draw() instead of plt.show() because the later blocks program execution. But draw() does not display the graphs.
Tried plt.pause(), the application gives RunTime error and crashes.
Also played with ion() / ioff().
Tried plt.show(block = False), the application crashes on second click on plot button.
I came across various backends that can be used with matplotlib and suspected that plt.show() might work well with other backends. Tried TkAgg, WxAgg, and others but no luck.
I would really appreciate if someone can help me with this...already tried for 3 days!!
Code sample:
from PyQt4 import QtCore, QtGui
import numpy as np
import matplotlib
matplotlib.use('TkAgg') #Trying different backends
import matplotlib.pyplot as plt
plt.rc('xtick', labelsize = 16)
plt.rc('ytick', labelsize = 16)
import FileDialog #These three imports needed for EXE
import tkFileDialog
import tkMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
#UI elements code...
def retranslateUi(self, MainWindow):
#Other code lines
def my_Plot_Function():
#Some calculations
plt.figure('My title')
plt.plot(x, y, label = 'My Label')
plt.grid(True)
plt.axhline(y = 0, color = 'k')
plt.xlabel(' X ', fontsize = 16)
plt.ylabel(' Y ', fontsize = 16)
plt.legend(prop={'size': 14})
plt.show()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

How can i display a resized image in python tkinter

I'm developing a GUI in Python using Tkinter to learn image processing. GUI's process flow would be as
Load image (jpg|png|...) => Resize/ thumbnail image (240 * 240) => Preview image
from Tkinter import *
import PIL
class Window:
def __init__(self, master):
master.title("Image Processing test")
master.minsize(800, 400)
from PIL import Image
im = Image.open("IMG_0562.png")
size = 240, 240
im.thumbnail(size)
p = im.tobytes()
# photo = PhotoImage(file="IMG_0562.gif")
# photo = BitmapImage(data=p)
w = Label(root, image=photo, width=240, height=240).grid(row=20, column=2)
self.photo = photo
root = Tk()
window = Window(root)
root.mainloop()
My problem is I couldn't get the image in a proper format to use it in Label. As Label only accepts PhotoImage and BitmapImage. PhotoImage doesn't support png or jpg file. So I used Image from PIL to load and resize my colored image. I've tried Image.tobitmap() and Image.tobytes() too but not useful in this case.
Solved the problem by saving the image in memory using io.BytesIO()
from Tkinter import *
from PIL import Image
import io
class Window:
def __init__(self, master):
master.title("Image Processing test")
master.minsize(800, 400)
im = Image.open("IMG_0562.png")
size = 240, 240
im.thumbnail(size)
b = io.BytesIO()
im.save(b, 'gif')
p = b.getvalue()
photo = BitmapImage(data=p)
w = Label(root, image=photo, width=240, height=240).grid(row=20, column=2)
self.photo = photo
root = Tk()
window = Window(root)
root.mainloop()

Stream video in python use pygame lib

I use library pygame in python to stream video from webcam of RasberryPi to my computer.
But I have a problem when receive image. It's not convert true image.
I've replaced my cam's ip adress with a placeholder <my_ip>.
This is my code:
Server:
import socket,os
from PIL import *
import pygame,sys
import pygame.camera
from pygame.locals import *
#Create server:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((<my_ip>,5000))
server.listen(5)
#Start Pygame
pygame.init()
pygame.camera.init()
screen = pygame.display.set_mode((320,240))
cam = pygame.camera.Camera("/dev/video0",(320,240),"RGB")
cam.start()
#Send data
while True:
s,add = server.accept()
print "Connected from",add
image = cam.get_image()
screen.blit(image,(0,0))
data = cam.get_raw()
s.sendall(data)
pygame.display.update()
#Interupt
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
Client:
import socket,sys
import pygame
from PIL import Image
#Create a var for storing an IP address:
ip = <my_ip>
#Start PyGame:
pygame.init()
screen = pygame.display.set_mode((320,240))
pygame.display.set_caption('Remote Webcam Viewer')
font = pygame.font.SysFont("Arial",14)
clock = pygame.time.Clock()
timer = 0
previousImage = ""
image = ""
#Main program loop:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#Receive data
if timer < 1:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((str(ip),5000))
data = client_socket.recv(1024000)
timer = 30
else:
timer -= 1
previousImage = image
#Convert image
try:
image = Image.fromstring("RGB",(120,90),data)
image = image.resize((320,240))
image = pygame.image.frombuffer(image.tostring(),(320,240),"RGB")
#Interupt
except:
image = previousImage
output = image
screen.blit(output,(0,0))
clock.tick(60)
pygame.display.flip()
But this is result after tranfer:
You are reassembling an image from the raw data received, but because you are sending a bigger resolution that you are re-creating, the pixels are 'overflowing' creating this effect.
the offending line is:
image = Image.fromstring("RGB",(120,90),data)
which should be:
image = Image.fromstring("RGB",(320,240),data)
*Not tested but should work.

opencv: saving images on mouseclick

So I've been messing around with opencv, and am trying to figure out how to capture an image on a mouse click. I've looked around a bit, but I just can't seem to find an answer. Here's the code that I have so far.
import numpy as np
import cv2
def captureFrame(event,frame):
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.imwrite('pictures/testFrame.png',frame) # want to save frame here
def main():
cv2.setMouseCallback('frame',captureFrame)
cap = cv2.VideoCapture(0)
cv2.namedWindow('frame',cv2.CV_WINDOW_AUTOSIZE)
while(True):
ret, frame = cap.read()
if ret:
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
The problem is that I want to pass the frame to the callback function captureFrame, but I'm not sure how to do that. Thanks!
Okay. So I figured out how to do this and I'm posting the fix below.
import numpy as np
import cv2
def main():
cap = cv2.VideoCapture(0)
cv2.namedWindow('frame',cv2.CV_WINDOW_AUTOSIZE)
count = 1
while(True):
ret, frame = cap.read()
cv2.setMouseCallback('frame',captureFrame,frame)
if ret:
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
def captureFrame(event,x,y,flags,frame):
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.imwrite('pictures/test.png',frame) # want to save frame here
if __name__ == "__main__":
main()
However, it is pretty unresponsive (as in I have to click multiple times to get a saved image, this may be because of a bad mouse though and i'll have to test that at a later time) and I haven't figured out why just yet. If anyone can explain why please do!

wxPython can't properly position a matplotlib block

I've taken the code to draw a rectangle over image form here, and modified it a little bit to suite my purposes. The only problem I have, it doesn't appear to be full screen, even though I make fr.ShowFullScreen(True). There is a grey area around the image.
Edited code is below (the rectangle part is not relevant):
# Use the wxPython backend of matplotlib
import matplotlib
matplotlib.use('WXAgg')
# Matplotlib elements used to draw the bounding rectangle
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
# wxPython stuff for the demo
import wx
class RectangleSelectImagePanel(wx.Panel):
def __init__(self, parent, pathToImage=None):
# Initialise the parent
wx.Panel.__init__(self, parent)
# Intitialise the matplotlib figure
self.figure = Figure(figsize=(20,15), dpi=80)
# Create an axes, turn off the labels and add them to the figure
self.axes = self.figure.add_subplot(1, 1, 1)
self.axes.set_axis_off()
# Add the figure to the wxFigureCanvas
self.canvas = FigureCanvas(self, -1, self.figure)
# Sizer to contain the canvas
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 0, wx.ALL)
self.SetSizer(self.sizer)
self.Fit()
def setImage(self, pathToImage):
'''Sets the background image of the canvas'''
import matplotlib.image as mpimg
# Load the image into matplotlib
image = matplotlib.image.imread(pathToImage)
# left in as anchor for image size
self.imageSize = image.shape[0:2]
print self.imageSize
#
# Add the image to the figure and redraw the canvas. Also ensure the aspect ratio of the image is retained.
self.axes.imshow(image, interpolation="quadric", aspect='auto')
self.canvas.draw()
if __name__ == "__main__":
# Create an demo application
app = wx.App()
# Create a frame and a RectangleSelectorPanel
fr = wx.Frame(None, title='test')
panel = RectangleSelectImagePanel(fr)
# Set the image in the panel
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
panel.setImage(imgpath)
# Start the demo app
fr.ShowFullScreen(True)
app.MainLoop()
probably what you need is subplots_adjust.
from pylab import *
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
image = matplotlib.image.imread(imgpath)
imshow(image, aspect='auto')
subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
This will produce a plot that has no margin around the image.
So, if you put
self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
after imshow line, you will get something closer to what you need.
Then, you will probably have to adjust the figsize parameter too. for my 1920 x 1080 display, I will need 1920.0/80 inch by 1080.0/80 inch so (24,13.5)