diff --git a/README.md b/README.md index f146e4c..e202abc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![Alt text](http://i.imgur.com/2ngZopS.jpg "Screenshot") +yuotube Vedio: https://youtu.be/_WUq3ABN3R0 + webcam-pulse-detector ----------------------- diff --git a/columns.txt b/columns.txt new file mode 100644 index 0000000..42e2657 --- /dev/null +++ b/columns.txt @@ -0,0 +1,14 @@ +age +sex +cp +trtbps +chol +fbs +restecg +thalachh +exng +oldpeak +slp +caa +thall +o2Saturation diff --git a/dataset/heart.csv b/dataset/heart.csv new file mode 100644 index 0000000..c211c93 --- /dev/null +++ b/dataset/heart.csv @@ -0,0 +1,304 @@ +age,sex,cp,trtbps,chol,fbs,restecg,thalachh,exng,oldpeak,slp,caa,thall,output +63,1,3,145,233,1,0,150,0,2.3,0,0,1,1 +37,1,2,130,250,0,1,187,0,3.5,0,0,2,1 +41,0,1,130,204,0,0,172,0,1.4,2,0,2,1 +56,1,1,120,236,0,1,178,0,0.8,2,0,2,1 +57,0,0,120,354,0,1,163,1,0.6,2,0,2,1 +57,1,0,140,192,0,1,148,0,0.4,1,0,1,1 +56,0,1,140,294,0,0,153,0,1.3,1,0,2,1 +44,1,1,120,263,0,1,173,0,0,2,0,3,1 +52,1,2,172,199,1,1,162,0,0.5,2,0,3,1 +57,1,2,150,168,0,1,174,0,1.6,2,0,2,1 +54,1,0,140,239,0,1,160,0,1.2,2,0,2,1 +48,0,2,130,275,0,1,139,0,0.2,2,0,2,1 +49,1,1,130,266,0,1,171,0,0.6,2,0,2,1 +64,1,3,110,211,0,0,144,1,1.8,1,0,2,1 +58,0,3,150,283,1,0,162,0,1,2,0,2,1 +50,0,2,120,219,0,1,158,0,1.6,1,0,2,1 +58,0,2,120,340,0,1,172,0,0,2,0,2,1 +66,0,3,150,226,0,1,114,0,2.6,0,0,2,1 +43,1,0,150,247,0,1,171,0,1.5,2,0,2,1 +69,0,3,140,239,0,1,151,0,1.8,2,2,2,1 +59,1,0,135,234,0,1,161,0,0.5,1,0,3,1 +44,1,2,130,233,0,1,179,1,0.4,2,0,2,1 +42,1,0,140,226,0,1,178,0,0,2,0,2,1 +61,1,2,150,243,1,1,137,1,1,1,0,2,1 +40,1,3,140,199,0,1,178,1,1.4,2,0,3,1 +71,0,1,160,302,0,1,162,0,0.4,2,2,2,1 +59,1,2,150,212,1,1,157,0,1.6,2,0,2,1 +51,1,2,110,175,0,1,123,0,0.6,2,0,2,1 +65,0,2,140,417,1,0,157,0,0.8,2,1,2,1 +53,1,2,130,197,1,0,152,0,1.2,0,0,2,1 +41,0,1,105,198,0,1,168,0,0,2,1,2,1 +65,1,0,120,177,0,1,140,0,0.4,2,0,3,1 +44,1,1,130,219,0,0,188,0,0,2,0,2,1 +54,1,2,125,273,0,0,152,0,0.5,0,1,2,1 +51,1,3,125,213,0,0,125,1,1.4,2,1,2,1 +46,0,2,142,177,0,0,160,1,1.4,0,0,2,1 +54,0,2,135,304,1,1,170,0,0,2,0,2,1 +54,1,2,150,232,0,0,165,0,1.6,2,0,3,1 +65,0,2,155,269,0,1,148,0,0.8,2,0,2,1 +65,0,2,160,360,0,0,151,0,0.8,2,0,2,1 +51,0,2,140,308,0,0,142,0,1.5,2,1,2,1 +48,1,1,130,245,0,0,180,0,0.2,1,0,2,1 +45,1,0,104,208,0,0,148,1,3,1,0,2,1 +53,0,0,130,264,0,0,143,0,0.4,1,0,2,1 +39,1,2,140,321,0,0,182,0,0,2,0,2,1 +52,1,1,120,325,0,1,172,0,0.2,2,0,2,1 +44,1,2,140,235,0,0,180,0,0,2,0,2,1 +47,1,2,138,257,0,0,156,0,0,2,0,2,1 +53,0,2,128,216,0,0,115,0,0,2,0,0,1 +53,0,0,138,234,0,0,160,0,0,2,0,2,1 +51,0,2,130,256,0,0,149,0,0.5,2,0,2,1 +66,1,0,120,302,0,0,151,0,0.4,1,0,2,1 +62,1,2,130,231,0,1,146,0,1.8,1,3,3,1 +44,0,2,108,141,0,1,175,0,0.6,1,0,2,1 +63,0,2,135,252,0,0,172,0,0,2,0,2,1 +52,1,1,134,201,0,1,158,0,0.8,2,1,2,1 +48,1,0,122,222,0,0,186,0,0,2,0,2,1 +45,1,0,115,260,0,0,185,0,0,2,0,2,1 +34,1,3,118,182,0,0,174,0,0,2,0,2,1 +57,0,0,128,303,0,0,159,0,0,2,1,2,1 +71,0,2,110,265,1,0,130,0,0,2,1,2,1 +54,1,1,108,309,0,1,156,0,0,2,0,3,1 +52,1,3,118,186,0,0,190,0,0,1,0,1,1 +41,1,1,135,203,0,1,132,0,0,1,0,1,1 +58,1,2,140,211,1,0,165,0,0,2,0,2,1 +35,0,0,138,183,0,1,182,0,1.4,2,0,2,1 +51,1,2,100,222,0,1,143,1,1.2,1,0,2,1 +45,0,1,130,234,0,0,175,0,0.6,1,0,2,1 +44,1,1,120,220,0,1,170,0,0,2,0,2,1 +62,0,0,124,209,0,1,163,0,0,2,0,2,1 +54,1,2,120,258,0,0,147,0,0.4,1,0,3,1 +51,1,2,94,227,0,1,154,1,0,2,1,3,1 +29,1,1,130,204,0,0,202,0,0,2,0,2,1 +51,1,0,140,261,0,0,186,1,0,2,0,2,1 +43,0,2,122,213,0,1,165,0,0.2,1,0,2,1 +55,0,1,135,250,0,0,161,0,1.4,1,0,2,1 +51,1,2,125,245,1,0,166,0,2.4,1,0,2,1 +59,1,1,140,221,0,1,164,1,0,2,0,2,1 +52,1,1,128,205,1,1,184,0,0,2,0,2,1 +58,1,2,105,240,0,0,154,1,0.6,1,0,3,1 +41,1,2,112,250,0,1,179,0,0,2,0,2,1 +45,1,1,128,308,0,0,170,0,0,2,0,2,1 +60,0,2,102,318,0,1,160,0,0,2,1,2,1 +52,1,3,152,298,1,1,178,0,1.2,1,0,3,1 +42,0,0,102,265,0,0,122,0,0.6,1,0,2,1 +67,0,2,115,564,0,0,160,0,1.6,1,0,3,1 +68,1,2,118,277,0,1,151,0,1,2,1,3,1 +46,1,1,101,197,1,1,156,0,0,2,0,3,1 +54,0,2,110,214,0,1,158,0,1.6,1,0,2,1 +58,0,0,100,248,0,0,122,0,1,1,0,2,1 +48,1,2,124,255,1,1,175,0,0,2,2,2,1 +57,1,0,132,207,0,1,168,1,0,2,0,3,1 +52,1,2,138,223,0,1,169,0,0,2,4,2,1 +54,0,1,132,288,1,0,159,1,0,2,1,2,1 +45,0,1,112,160,0,1,138,0,0,1,0,2,1 +53,1,0,142,226,0,0,111,1,0,2,0,3,1 +62,0,0,140,394,0,0,157,0,1.2,1,0,2,1 +52,1,0,108,233,1,1,147,0,0.1,2,3,3,1 +43,1,2,130,315,0,1,162,0,1.9,2,1,2,1 +53,1,2,130,246,1,0,173,0,0,2,3,2,1 +42,1,3,148,244,0,0,178,0,0.8,2,2,2,1 +59,1,3,178,270,0,0,145,0,4.2,0,0,3,1 +63,0,1,140,195,0,1,179,0,0,2,2,2,1 +42,1,2,120,240,1,1,194,0,0.8,0,0,3,1 +50,1,2,129,196,0,1,163,0,0,2,0,2,1 +68,0,2,120,211,0,0,115,0,1.5,1,0,2,1 +69,1,3,160,234,1,0,131,0,0.1,1,1,2,1 +45,0,0,138,236,0,0,152,1,0.2,1,0,2,1 +50,0,1,120,244,0,1,162,0,1.1,2,0,2,1 +50,0,0,110,254,0,0,159,0,0,2,0,2,1 +64,0,0,180,325,0,1,154,1,0,2,0,2,1 +57,1,2,150,126,1,1,173,0,0.2,2,1,3,1 +64,0,2,140,313,0,1,133,0,0.2,2,0,3,1 +43,1,0,110,211,0,1,161,0,0,2,0,3,1 +55,1,1,130,262,0,1,155,0,0,2,0,2,1 +37,0,2,120,215,0,1,170,0,0,2,0,2,1 +41,1,2,130,214,0,0,168,0,2,1,0,2,1 +56,1,3,120,193,0,0,162,0,1.9,1,0,3,1 +46,0,1,105,204,0,1,172,0,0,2,0,2,1 +46,0,0,138,243,0,0,152,1,0,1,0,2,1 +64,0,0,130,303,0,1,122,0,2,1,2,2,1 +59,1,0,138,271,0,0,182,0,0,2,0,2,1 +41,0,2,112,268,0,0,172,1,0,2,0,2,1 +54,0,2,108,267,0,0,167,0,0,2,0,2,1 +39,0,2,94,199,0,1,179,0,0,2,0,2,1 +34,0,1,118,210,0,1,192,0,0.7,2,0,2,1 +47,1,0,112,204,0,1,143,0,0.1,2,0,2,1 +67,0,2,152,277,0,1,172,0,0,2,1,2,1 +52,0,2,136,196,0,0,169,0,0.1,1,0,2,1 +74,0,1,120,269,0,0,121,1,0.2,2,1,2,1 +54,0,2,160,201,0,1,163,0,0,2,1,2,1 +49,0,1,134,271,0,1,162,0,0,1,0,2,1 +42,1,1,120,295,0,1,162,0,0,2,0,2,1 +41,1,1,110,235,0,1,153,0,0,2,0,2,1 +41,0,1,126,306,0,1,163,0,0,2,0,2,1 +49,0,0,130,269,0,1,163,0,0,2,0,2,1 +60,0,2,120,178,1,1,96,0,0,2,0,2,1 +62,1,1,128,208,1,0,140,0,0,2,0,2,1 +57,1,0,110,201,0,1,126,1,1.5,1,0,1,1 +64,1,0,128,263,0,1,105,1,0.2,1,1,3,1 +51,0,2,120,295,0,0,157,0,0.6,2,0,2,1 +43,1,0,115,303,0,1,181,0,1.2,1,0,2,1 +42,0,2,120,209,0,1,173,0,0,1,0,2,1 +67,0,0,106,223,0,1,142,0,0.3,2,2,2,1 +76,0,2,140,197,0,2,116,0,1.1,1,0,2,1 +70,1,1,156,245,0,0,143,0,0,2,0,2,1 +44,0,2,118,242,0,1,149,0,0.3,1,1,2,1 +60,0,3,150,240,0,1,171,0,0.9,2,0,2,1 +44,1,2,120,226,0,1,169,0,0,2,0,2,1 +42,1,2,130,180,0,1,150,0,0,2,0,2,1 +66,1,0,160,228,0,0,138,0,2.3,2,0,1,1 +71,0,0,112,149,0,1,125,0,1.6,1,0,2,1 +64,1,3,170,227,0,0,155,0,0.6,1,0,3,1 +66,0,2,146,278,0,0,152,0,0,1,1,2,1 +39,0,2,138,220,0,1,152,0,0,1,0,2,1 +58,0,0,130,197,0,1,131,0,0.6,1,0,2,1 +47,1,2,130,253,0,1,179,0,0,2,0,2,1 +35,1,1,122,192,0,1,174,0,0,2,0,2,1 +58,1,1,125,220,0,1,144,0,0.4,1,4,3,1 +56,1,1,130,221,0,0,163,0,0,2,0,3,1 +56,1,1,120,240,0,1,169,0,0,0,0,2,1 +55,0,1,132,342,0,1,166,0,1.2,2,0,2,1 +41,1,1,120,157,0,1,182,0,0,2,0,2,1 +38,1,2,138,175,0,1,173,0,0,2,4,2,1 +38,1,2,138,175,0,1,173,0,0,2,4,2,1 +67,1,0,160,286,0,0,108,1,1.5,1,3,2,0 +67,1,0,120,229,0,0,129,1,2.6,1,2,3,0 +62,0,0,140,268,0,0,160,0,3.6,0,2,2,0 +63,1,0,130,254,0,0,147,0,1.4,1,1,3,0 +53,1,0,140,203,1,0,155,1,3.1,0,0,3,0 +56,1,2,130,256,1,0,142,1,0.6,1,1,1,0 +48,1,1,110,229,0,1,168,0,1,0,0,3,0 +58,1,1,120,284,0,0,160,0,1.8,1,0,2,0 +58,1,2,132,224,0,0,173,0,3.2,2,2,3,0 +60,1,0,130,206,0,0,132,1,2.4,1,2,3,0 +40,1,0,110,167,0,0,114,1,2,1,0,3,0 +60,1,0,117,230,1,1,160,1,1.4,2,2,3,0 +64,1,2,140,335,0,1,158,0,0,2,0,2,0 +43,1,0,120,177,0,0,120,1,2.5,1,0,3,0 +57,1,0,150,276,0,0,112,1,0.6,1,1,1,0 +55,1,0,132,353,0,1,132,1,1.2,1,1,3,0 +65,0,0,150,225,0,0,114,0,1,1,3,3,0 +61,0,0,130,330,0,0,169,0,0,2,0,2,0 +58,1,2,112,230,0,0,165,0,2.5,1,1,3,0 +50,1,0,150,243,0,0,128,0,2.6,1,0,3,0 +44,1,0,112,290,0,0,153,0,0,2,1,2,0 +60,1,0,130,253,0,1,144,1,1.4,2,1,3,0 +54,1,0,124,266,0,0,109,1,2.2,1,1,3,0 +50,1,2,140,233,0,1,163,0,0.6,1,1,3,0 +41,1,0,110,172,0,0,158,0,0,2,0,3,0 +51,0,0,130,305,0,1,142,1,1.2,1,0,3,0 +58,1,0,128,216,0,0,131,1,2.2,1,3,3,0 +54,1,0,120,188,0,1,113,0,1.4,1,1,3,0 +60,1,0,145,282,0,0,142,1,2.8,1,2,3,0 +60,1,2,140,185,0,0,155,0,3,1,0,2,0 +59,1,0,170,326,0,0,140,1,3.4,0,0,3,0 +46,1,2,150,231,0,1,147,0,3.6,1,0,2,0 +67,1,0,125,254,1,1,163,0,0.2,1,2,3,0 +62,1,0,120,267,0,1,99,1,1.8,1,2,3,0 +65,1,0,110,248,0,0,158,0,0.6,2,2,1,0 +44,1,0,110,197,0,0,177,0,0,2,1,2,0 +60,1,0,125,258,0,0,141,1,2.8,1,1,3,0 +58,1,0,150,270,0,0,111,1,0.8,2,0,3,0 +68,1,2,180,274,1,0,150,1,1.6,1,0,3,0 +62,0,0,160,164,0,0,145,0,6.2,0,3,3,0 +52,1,0,128,255,0,1,161,1,0,2,1,3,0 +59,1,0,110,239,0,0,142,1,1.2,1,1,3,0 +60,0,0,150,258,0,0,157,0,2.6,1,2,3,0 +49,1,2,120,188,0,1,139,0,2,1,3,3,0 +59,1,0,140,177,0,1,162,1,0,2,1,3,0 +57,1,2,128,229,0,0,150,0,0.4,1,1,3,0 +61,1,0,120,260,0,1,140,1,3.6,1,1,3,0 +39,1,0,118,219,0,1,140,0,1.2,1,0,3,0 +61,0,0,145,307,0,0,146,1,1,1,0,3,0 +56,1,0,125,249,1,0,144,1,1.2,1,1,2,0 +43,0,0,132,341,1,0,136,1,3,1,0,3,0 +62,0,2,130,263,0,1,97,0,1.2,1,1,3,0 +63,1,0,130,330,1,0,132,1,1.8,2,3,3,0 +65,1,0,135,254,0,0,127,0,2.8,1,1,3,0 +48,1,0,130,256,1,0,150,1,0,2,2,3,0 +63,0,0,150,407,0,0,154,0,4,1,3,3,0 +55,1,0,140,217,0,1,111,1,5.6,0,0,3,0 +65,1,3,138,282,1,0,174,0,1.4,1,1,2,0 +56,0,0,200,288,1,0,133,1,4,0,2,3,0 +54,1,0,110,239,0,1,126,1,2.8,1,1,3,0 +70,1,0,145,174,0,1,125,1,2.6,0,0,3,0 +62,1,1,120,281,0,0,103,0,1.4,1,1,3,0 +35,1,0,120,198,0,1,130,1,1.6,1,0,3,0 +59,1,3,170,288,0,0,159,0,0.2,1,0,3,0 +64,1,2,125,309,0,1,131,1,1.8,1,0,3,0 +47,1,2,108,243,0,1,152,0,0,2,0,2,0 +57,1,0,165,289,1,0,124,0,1,1,3,3,0 +55,1,0,160,289,0,0,145,1,0.8,1,1,3,0 +64,1,0,120,246,0,0,96,1,2.2,0,1,2,0 +70,1,0,130,322,0,0,109,0,2.4,1,3,2,0 +51,1,0,140,299,0,1,173,1,1.6,2,0,3,0 +58,1,0,125,300,0,0,171,0,0,2,2,3,0 +60,1,0,140,293,0,0,170,0,1.2,1,2,3,0 +77,1,0,125,304,0,0,162,1,0,2,3,2,0 +35,1,0,126,282,0,0,156,1,0,2,0,3,0 +70,1,2,160,269,0,1,112,1,2.9,1,1,3,0 +59,0,0,174,249,0,1,143,1,0,1,0,2,0 +64,1,0,145,212,0,0,132,0,2,1,2,1,0 +57,1,0,152,274,0,1,88,1,1.2,1,1,3,0 +56,1,0,132,184,0,0,105,1,2.1,1,1,1,0 +48,1,0,124,274,0,0,166,0,0.5,1,0,3,0 +56,0,0,134,409,0,0,150,1,1.9,1,2,3,0 +66,1,1,160,246,0,1,120,1,0,1,3,1,0 +54,1,1,192,283,0,0,195,0,0,2,1,3,0 +69,1,2,140,254,0,0,146,0,2,1,3,3,0 +51,1,0,140,298,0,1,122,1,4.2,1,3,3,0 +43,1,0,132,247,1,0,143,1,0.1,1,4,3,0 +62,0,0,138,294,1,1,106,0,1.9,1,3,2,0 +67,1,0,100,299,0,0,125,1,0.9,1,2,2,0 +59,1,3,160,273,0,0,125,0,0,2,0,2,0 +45,1,0,142,309,0,0,147,1,0,1,3,3,0 +58,1,0,128,259,0,0,130,1,3,1,2,3,0 +50,1,0,144,200,0,0,126,1,0.9,1,0,3,0 +62,0,0,150,244,0,1,154,1,1.4,1,0,2,0 +38,1,3,120,231,0,1,182,1,3.8,1,0,3,0 +66,0,0,178,228,1,1,165,1,1,1,2,3,0 +52,1,0,112,230,0,1,160,0,0,2,1,2,0 +53,1,0,123,282,0,1,95,1,2,1,2,3,0 +63,0,0,108,269,0,1,169,1,1.8,1,2,2,0 +54,1,0,110,206,0,0,108,1,0,1,1,2,0 +66,1,0,112,212,0,0,132,1,0.1,2,1,2,0 +55,0,0,180,327,0,2,117,1,3.4,1,0,2,0 +49,1,2,118,149,0,0,126,0,0.8,2,3,2,0 +54,1,0,122,286,0,0,116,1,3.2,1,2,2,0 +56,1,0,130,283,1,0,103,1,1.6,0,0,3,0 +46,1,0,120,249,0,0,144,0,0.8,2,0,3,0 +61,1,3,134,234,0,1,145,0,2.6,1,2,2,0 +67,1,0,120,237,0,1,71,0,1,1,0,2,0 +58,1,0,100,234,0,1,156,0,0.1,2,1,3,0 +47,1,0,110,275,0,0,118,1,1,1,1,2,0 +52,1,0,125,212,0,1,168,0,1,2,2,3,0 +58,1,0,146,218,0,1,105,0,2,1,1,3,0 +57,1,1,124,261,0,1,141,0,0.3,2,0,3,0 +58,0,1,136,319,1,0,152,0,0,2,2,2,0 +61,1,0,138,166,0,0,125,1,3.6,1,1,2,0 +42,1,0,136,315,0,1,125,1,1.8,1,0,1,0 +52,1,0,128,204,1,1,156,1,1,1,0,0,0 +59,1,2,126,218,1,1,134,0,2.2,1,1,1,0 +40,1,0,152,223,0,1,181,0,0,2,0,3,0 +61,1,0,140,207,0,0,138,1,1.9,2,1,3,0 +46,1,0,140,311,0,1,120,1,1.8,1,2,3,0 +59,1,3,134,204,0,1,162,0,0.8,2,2,2,0 +57,1,1,154,232,0,0,164,0,0,2,1,2,0 +57,1,0,110,335,0,1,143,1,3,1,1,3,0 +55,0,0,128,205,0,2,130,1,2,1,1,3,0 +61,1,0,148,203,0,1,161,0,0,2,1,3,0 +58,1,0,114,318,0,2,140,0,4.4,0,3,1,0 +58,0,0,170,225,1,0,146,1,2.8,1,2,1,0 +67,1,2,152,212,0,0,150,0,0.8,1,0,3,0 +44,1,0,120,169,0,1,144,1,2.8,0,0,1,0 +63,1,0,140,187,0,0,144,1,4,2,2,3,0 +63,0,0,124,197,0,1,136,1,0,1,0,2,0 +59,1,0,164,176,1,0,90,0,1,1,2,1,0 +57,0,0,140,241,0,1,123,1,0.2,1,0,3,0 +45,1,3,110,264,0,1,132,0,1.2,1,0,3,0 +68,1,0,144,193,1,1,141,0,3.4,1,2,3,0 +57,1,0,130,131,0,1,115,1,1.2,1,1,3,0 +57,0,1,130,236,0,0,174,0,0,1,1,2,0 diff --git a/dataset/o2Saturation.csv b/dataset/o2Saturation.csv new file mode 100644 index 0000000..5470b6b --- /dev/null +++ b/dataset/o2Saturation.csv @@ -0,0 +1,3586 @@ +98.6 +98.6 +98.6 +98.6 +98.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +97 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.5 +98.1 +98.6 +98.6 +98 +98.1 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98.6 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98.6 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +98.1 +98 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.1 +97.5 +97.5 +97.5 +97.6 +97.6 +97.5 +97.6 +97.6 +97.6 +97.6 +97.5 +97.6 +97.5 +97.5 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.5 +97.6 +97.5 +97.5 +97.6 +97.6 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.5 +97.6 +98.1 +98.6 +98.6 +98 +97.6 +97.6 +97.5 +97.6 +97.6 +97.6 +97.5 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.5 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +98.1 +98 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98 +98.1 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.5 +97.5 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.5 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.1 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98 +97.6 +98.2 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +96.9 +96.5 +96.5 +97.1 +97.6 +97.6 +97.6 +97.6 +96.9 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.1 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +98.2 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +96.9 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.2 +97.6 +97.6 +97.6 +96.9 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +96.5 +97.2 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +97.9 +97.6 +97.6 +96.9 +96.5 +96.5 +96.5 +97.2 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +97.9 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.2 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +98.9 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +97.9 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +97.6 +98.3 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +98.9 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.9 +98.6 +99.3 +99.6 +98.9 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +98.9 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +98.9 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.9 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.9 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +99.3 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +99.3 +99.6 +98.8 +99.3 +98.8 +99.3 +99.6 +99.6 +98.8 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 +98.6 diff --git a/get_pulse.py b/get_pulse.py index 5ba151d..83af61e 100644 --- a/get_pulse.py +++ b/get_pulse.py @@ -6,12 +6,12 @@ import numpy as np import datetime #TODO: work on serial port comms, if anyone asks for it -#from serial import Serial import socket import sys +import joblib +import pandas as pd class getPulseApp(object): - """ Python application that finds a face in a webcam stream, then isolates the forehead. @@ -46,7 +46,7 @@ def __init__(self, args): port = int(port) self.udp = (ip, port) self.sock = socket.socket(socket.AF_INET, # Internet - socket.SOCK_DGRAM) # UDP + socket.SOCK_DGRAM) # UDP self.cameras = [] self.selected_cam = 0 @@ -56,9 +56,9 @@ def __init__(self, args): self.cameras.append(camera) else: break - self.w, self.h = 0, 0 + self.w, self.w, = 0, 0 self.pressed = 0 - # Containerized analysis of recieved image frames (an openMDAO assembly) + # Containerized analysis of received image frames (an openMDAO assembly) # is defined next. # This assembly is designed to handle all image & signal analysis, @@ -67,7 +67,7 @@ def __init__(self, args): # Basically, everything that isn't communication # to the camera device or part of the GUI - self.processor = findFaceGetPulse(bpm_limits=[50, 160], + self.processor = findFaceGetPulse(bpm_limits=[60, 160], data_spike_limit=2500., face_detector_smoothness=10.) @@ -82,6 +82,11 @@ def __init__(self, args): "c": self.toggle_cam, "f": self.write_csv} + # Load the columns and model for heart attack prediction + with open('columns.txt', 'r') as f: + self.columns = [line.strip() for line in f] + self.heart_attack_model = joblib.load('heart_attack_model.pkl') + def toggle_cam(self): if len(self.cameras) > 1: self.processor.find_faces = True @@ -94,22 +99,66 @@ def write_csv(self): """ Writes current data to a csv file """ - fn = "Webcam-pulse" + str(datetime.datetime.now()) - fn = fn.replace(":", "_").replace(".", "_") + fna = "Webcam-pulse" + str(datetime.datetime.now()) + fna = fna.replace(":", "_").replace(".", "_") data = np.vstack((self.processor.times, self.processor.samples)).T - np.savetxt(fn + ".csv", data, delimiter=',') - print("Writing csv") + np.savetxt(fna + ".csv", data, delimiter=',') + print("Writing csv with bpm") def toggle_search(self): """ Toggles a motion lock on the processor's face detection component. Locking the forehead location in place significantly improves - data quality, once a forehead has been sucessfully isolated. + data quality, once a forehead has been successfully isolated. """ - #state = self.processor.find_faces.toggle() state = self.processor.find_faces_toggle() print("face detection lock =", not state) + # Initialize attributes for heart attack prediction + self.age = None + self.sex = None + self.o2_saturation = None + self.cp = None + + def set_age(self, age): + self.age = age + + def set_sex(self, sex): + self.sex = sex + + def set_o2_saturation(self, o2_saturation): + self.o2_saturation = o2_saturation + + def set_cp(self, cp): + self.cp = cp + + def predict_heart_attack(self): + # Collect the necessary features for prediction + features = { + 'age': self.age, + 'sex': self.sex, + 'o2Saturation': self.o2_saturation, + 'cp': self.cp + } + print(features.keys()) + # Example: Populate features with default values if needed + if 'cp' not in features: + features['cp'] = 0 # Define a sensible default + for feature in self.columns: + if feature not in features: + print(f"Missing feature: {feature}") + # Optionally, handle missing keys with defaults or warnings + features[feature] = 0 # Example default, adjust as needed + + # Ensure the features are in the correct order + feature_values = [features[feature] for feature in self.columns] + print(self.columns) + expected_columns = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', 'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'thal'] + print(all(col in self.columns for col in expected_columns)) # Should be True + + # Predict heart attack + prediction = self.heart_attack_model.predict([feature_values]) + return prediction[0] def toggle_display_plot(self): """ @@ -195,6 +244,17 @@ def main_loop(self): if self.send_udp: self.sock.sendto(str(self.processor.bpm), self.udp) + # Example: Set the attributes with actual data + self.set_age(45) # Replace with actual data + self.set_sex(1) # Replace with actual data + self.set_o2_saturation(98.6) # Replace with actual data + self.set_cp(3) # Replace with actual data + + # Predict heart attack + heart_attack_risk = self.predict_heart_attack() + if heart_attack_risk == 1: + print("Warning: High risk of heart attack detected!") + # handle any key presses self.key_handler() @@ -210,4 +270,4 @@ def main_loop(self): args = parser.parse_args() App = getPulseApp(args) while True: - App.main_loop() + App.main_loop() \ No newline at end of file diff --git a/get_pulse.spec b/get_pulse.spec deleted file mode 100644 index cf298aa..0000000 --- a/get_pulse.spec +++ /dev/null @@ -1,28 +0,0 @@ -# -*- mode: python -*- -a = Analysis(['get_pulse.py'], - pathex=[ - '/Users/tristanhearn/Documents/thearn_repos/webcam-pulse-detector'], - hiddenimports=[], - hookspath=None, - runtime_hooks=None) -a.datas += [ - ('haarcascade_frontalface_alt.xml', 'haarcascade_frontalface_alt.xml', 'DATA')] -pyz = PYZ(a.pure) -exe = EXE(pyz, - a.scripts, - exclude_binaries=True, - name='get_pulse', - debug=False, - strip=None, - upx=True, - console=False) -coll = COLLECT(exe, - a.binaries, - a.zipfiles, - a.datas, - strip=None, - upx=True, - name='get_pulse') -app = BUNDLE(coll, - name='get_pulse.app', - icon=None) diff --git a/heart_attack_model.pkl b/heart_attack_model.pkl new file mode 100644 index 0000000..a8fb72b Binary files /dev/null and b/heart_attack_model.pkl differ diff --git a/heart_attack_predictor.py b/heart_attack_predictor.py new file mode 100644 index 0000000..fbed93f --- /dev/null +++ b/heart_attack_predictor.py @@ -0,0 +1,37 @@ +import pandas as pd +from sklearn.model_selection import train_test_split +from sklearn.ensemble import RandomForestClassifier +from sklearn.metrics import accuracy_score +import joblib + +# Load datasets +heart_data = pd.read_csv('dataset/heart.csv') +o2_data = pd.read_csv('dataset/o2Saturation.csv', header=None, names=['o2Saturation']) + +# Preprocess data +# Assuming o2Saturation is an additional feature to heart_data +heart_data['o2Saturation'] = o2_data['o2Saturation'] + +# Split data into features and target +X = heart_data.drop('output', axis=1) +y = heart_data['output'] + +# Save the columns of X +with open('columns.txt', 'w') as f: + for column in X.columns: + f.write(f"{column}\n") + +# Split data into training and testing sets +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# Train a RandomForestClassifier +model = RandomForestClassifier(n_estimators=100, random_state=42) +model.fit(X_train, y_train) + +# Evaluate the model +y_pred = model.predict(X_test) +accuracy = accuracy_score(y_test, y_pred) +print(f'Model Accuracy: {accuracy * 100:.2f}%') + +# Save the model +joblib.dump(model, 'heart_attack_model.pkl') \ No newline at end of file diff --git a/lib/device.py b/lib/device.py index e80665c..9fc8232 100644 --- a/lib/device.py +++ b/lib/device.py @@ -1,7 +1,7 @@ import cv2, time -#TODO: fix ipcam -#import urllib2, base64 +import base64 # Add base64 import import numpy as np +import urllib.request # Add this import class ipCamera(object): @@ -9,11 +9,11 @@ def __init__(self,url, user = None, password = None): self.url = url auth_encoded = base64.encodestring('%s:%s' % (user, password))[:-1] - self.req = urllib2.Request(self.url) + self.req = urllib.request.Request(self.url) # Update urllib2 to urllib.request self.req.add_header('Authorization', 'Basic %s' % auth_encoded) def get_frame(self): - response = urllib2.urlopen(self.req) + response = urllib.request.urlopen(self.req) # Update urllib2 to urllib.request img_array = np.asarray(bytearray(response.read()), dtype=np.uint8) frame = cv2.imdecode(img_array, 1) return frame diff --git a/lib/imageProcess.py b/lib/imageProcess.py index 8ce5da1..00845cd 100644 --- a/lib/imageProcess.py +++ b/lib/imageProcess.py @@ -1,5 +1,4 @@ -from openmdao.lib.datatypes.api import Float, Dict, Array, List, Int, Bool -from openmdao.main.api import Component, Assembly +from openmdao.api import ExplicitComponent, Problem, Group, IndepVarComp import numpy as np import time import cv2 @@ -8,8 +7,7 @@ Whole-frame image processing components & helper methods """ - -class RGBSplit(Component): +class RGBSplit(ExplicitComponent): """ Extract the red, green, and blue channels from an (n,m,3) shaped @@ -20,19 +18,19 @@ class RGBSplit(Component): def __init__(self): super(RGBSplit, self).__init__() - self.add("frame_in", Array(iotype="in")) - - self.add("R", Array(iotype="out")) - self.add("G", Array(iotype="out")) - self.add("B", Array(iotype="out")) + self.add_input("frame_in", val=np.zeros((1, 1, 3))) + self.add_output("R", val=np.zeros((1, 1))) + self.add_output("G", val=np.zeros((1, 1))) + self.add_output("B", val=np.zeros((1, 1))) - def execute(self): - self.R = self.frame_in[:, :, 0] - self.G = self.frame_in[:, :, 1] - self.B = self.frame_in[:, :, 2] + def compute(self, inputs, outputs): + frame_in = inputs['frame_in'] + outputs['R'] = frame_in[:, :, 0] + outputs['G'] = frame_in[:, :, 1] + outputs['B'] = frame_in[:, :, 2] -class RGBmuxer(Component): +class RGBmuxer(ExplicitComponent): """ Take three (m,n) matrices of equal size and combine them into a single @@ -41,18 +39,19 @@ class RGBmuxer(Component): def __init__(self): super(RGBmuxer, self).__init__() - self.add("R", Array(iotype="in")) - self.add("G", Array(iotype="in")) - self.add("B", Array(iotype="in")) - - self.add("frame_out", Array(iotype="out")) + self.add_input("R", val=np.zeros((1, 1))) + self.add_input("G", val=np.zeros((1, 1))) + self.add_input("B", val=np.zeros((1, 1))) + self.add_output("frame_out", val=np.zeros((1, 1, 3))) - def execute(self): - m, n = self.R.shape - self.frame_out = cv2.merge([self.R, self.G, self.B]) + def compute(self, inputs, outputs): + R = inputs['R'] + G = inputs['G'] + B = inputs['B'] + outputs['frame_out'] = cv2.merge([R, G, B]) -class CVwrapped(Component): +class CVwrapped(ExplicitComponent): """ Generic wrapper to take the simpler functions from the cv2 or scipy image @@ -68,14 +67,15 @@ class CVwrapped(Component): def __init__(self, func, *args, **kwargs): super(CVwrapped, self).__init__() - self.add("frame_in", Array(iotype="in")) - self.add("frame_out", Array(iotype="out")) + self.add_input("frame_in", val=np.zeros((1, 1, 3))) + self.add_output("frame_out", val=np.zeros((1, 1, 3))) self._func = func self._args = args self._kwargs = kwargs - def execute(self): - self.frame_out = self._func(self.frame_in, *self._args, **self._kwargs) + def compute(self, inputs, outputs): + frame_in = inputs['frame_in'] + outputs['frame_out'] = self._func(frame_in, *self._args, **self._kwargs) class Grayscale(CVwrapped): @@ -100,36 +100,37 @@ def __init__(self): super(equalizeContrast, self).__init__(cv2.equalizeHist) -class showBPMtext(Component): +class showBPMtext(ExplicitComponent): """ Shows the estimated BPM in the image frame """ - ready = Bool(False, iotype="in") - bpm = Float(iotype="in") - x = Int(iotype="in") - y = Int(iotype="in") - fps = Float(iotype="in") - size = Float(iotype="in") - n = Int(iotype="in") + ready = False + bpm = 0.0 + x = 0 + y = 0 + fps = 0.0 + size = 0.0 + n = 0 def __init__(self): super(showBPMtext, self).__init__() - self.add("frame_in", Array(iotype="in")) - self.add("frame_out", Array(iotype="out")) + self.add_input("frame_in", val=np.zeros((1, 1, 3))) + self.add_output("frame_out", val=np.zeros((1, 1, 3))) self.bpms = [] - def execute(self): + def compute(self, inputs, outputs): + frame_in = inputs['frame_in'] self.bpms.append([time.time(), self.bpm]) if self.ready: col = (0, 255, 0) - text = "%0.1f bpm" % self.bpm + text = "%0.5f bpm" % self.bpm tsize = 2 else: col = (100, 255, 100) gap = (self.n - self.size) / self.fps - text = "(estimate: %0.1f bpm, wait %0.0f s)" % (self.bpm, gap) + text = "(estimate: %0.5f bpm, wait %0.2f s)" % (self.bpm, gap) tsize = 1 - cv2.putText(self.frame_in, text, + cv2.putText(frame_in, text, (self.x, self.y), cv2.FONT_HERSHEY_PLAIN, tsize, col) - self.frame_out = self.frame_in + outputs['frame_out'] = frame_in diff --git a/lib/processors_noopenmdao.py b/lib/processors_noopenmdao.py index 2dc39db..0b98745 100644 --- a/lib/processors_noopenmdao.py +++ b/lib/processors_noopenmdao.py @@ -1,3 +1,5 @@ +from errno import ERANGE +from matplotlib.widgets import RangeSlider import numpy as np import time import cv2 @@ -58,7 +60,7 @@ def find_faces_toggle(self): def get_faces(self): return - def shift(self, detected): + def shift(self, detected): x, y, w, h = detected center = np.array([x + 0.5 * w, y + 0.5 * h]) shift = np.linalg.norm(center - self.last_center) @@ -98,18 +100,18 @@ def plot(self): idx = np.where((freqs > 50) & (freqs < 180)) pylab.figure() n = data.shape[0] - for k in xrange(n): + for k in RangeSlider(n): pylab.subplot(n, 1, k + 1) pylab.plot(self.times, data[k]) pylab.savefig("data.png") pylab.figure() - for k in xrange(self.output_dim): + for k in ERANGE(self.output_dim): pylab.subplot(self.output_dim, 1, k + 1) pylab.plot(self.times, self.pcadata[k]) pylab.savefig("data_pca.png") pylab.figure() - for k in xrange(self.output_dim): + for k in np.arange(self.output_dim): pylab.subplot(self.output_dim, 1, k + 1) pylab.plot(freqs[idx], self.fft[k][idx]) pylab.savefig("data_fft.png") @@ -204,6 +206,12 @@ def run(self, cam): pfreq = freqs[idx] self.freqs = pfreq self.fft = pruned + + if pruned.size == 0: + # Handle the case where pruned is empty + print("No valid frequency components found.") + return + idx2 = np.argmax(pruned) t = (np.sin(phase[idx2]) + 1.) / 2. diff --git a/setup.py b/setup.py deleted file mode 100644 index 3fe12cf..0000000 --- a/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -This is a setup.py script generated by py2applet - -Usage: - python setup.py py2app -""" - -from setuptools import setup - -APP = ['get_pulse.py'] -DATA_FILES = ['cascades/haarcascade_frontalface_alt.xml'] -OPTIONS = {'argv_emulation': True} - -setup( - app=APP, - data_files=DATA_FILES, - options={'py2app': OPTIONS}, - setup_requires=['py2app'], -)