Full Code of HazSyl1/Virtual_Calculator for AI

main d6dbd7dd5264 cached
8 files
11.8 KB
3.4k tokens
11 symbols
1 requests
Download .txt
Repository: HazSyl1/Virtual_Calculator
Branch: main
Commit: d6dbd7dd5264
Files: 8
Total size: 11.8 KB

Directory structure:
gitextract_mpzxbp6l/

├── .gitignore
├── Dockerfile
├── README.md
├── app.py
├── main.py
├── requirements.txt
├── static/
│   └── serve.js
└── templates/
    └── index.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/virtualC

================================================
FILE: Dockerfile
================================================
FROM python:3.9-slim 

WORKDIR /
COPY . .
RUN apt-get update && apt-get install ffmpeg libsm6 libxext6  -y
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        build-essential \
        libopencv-dev \
    && rm -rf /var/lib/apt/lists/*
RUN pip install -r requirements.txt
EXPOSE 8080

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

================================================
FILE: README.md
================================================
A virtual calculator build using OpenCV.
DEMO: https://www.youtube.com/watch?v=M8ZjUq8QD10


================================================
FILE: app.py
================================================
from flask import Flask,render_template,Response, jsonify , request
import cv2 as cv 
from main import serve
import numpy as np
import base64
from flask_cors import CORS





app=Flask(__name__)
CORS(app)


# camera=cv.VideoCapture(2)
# camera.set(3,1280) #width
# camera.set(4,720) #height
history=[]




# def generate_frames():
#     while True:
       
#         success,frame=camera.read()
#         if not success:
#             break
#         else:
#             try:
#                 frame,finEq=serve(frame)
#             except:
#                 pass
#             if finEq!="":
#                 global history
#                 history.append(finEq)
#                 print(history)
#             ret,buffer=cv.imencode('.jpg',frame)
#             frame=buffer.tobytes()
#             yield(b'--frame\r\n'
#                 b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
        

@app.route('/process_frame',methods=['POST'])
def process_frame():
    try:
        file=request.files['frame']
        
        file_byte=np.frombuffer(file.read(),np.uint8)
        frame=cv.imdecode(file_byte,cv.IMREAD_COLOR)
        frame,finEq=serve(frame)
        # print("GOT PROCESSED FILE")
        _,buffer=cv.imencode('.jpg',frame)
        processed_frame=base64.b64encode(buffer).decode('utf-8')
        if finEq!="":
            global history
            history.append(finEq)
            
            print(history)
        return jsonify(success=True, frame =processed_frame)
    except Exception as e:
        print(e)
        return jsonify(success=False,message=str(e)) 
        

@app.route('/get_history')
def update_history():
    global history
    print(history)
    return jsonify(success=True,history=history)

@app.route('/')
def index():
    # return "Starting"
    global history
    return render_template('index.html',history=history)

@app.route('/video')
def video_function():
    return Response(generate_frames(),mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__=="__main__":
    app.run(debug=True)

================================================
FILE: main.py
================================================
import cv2 as cv
from cvzone.HandTrackingModule import HandDetector

class Button:
    def __init__(self, pos, width, height, value):
        self.pos = pos
        self.width = width
        self.height = height
        self.value = value

    def draw(self, frame):
        cv.rectangle(frame, self.pos, (self.pos[0] + self.width, self.pos[1] + self.height),
                     (225, 255, 225), cv.FILLED)
        cv.rectangle(frame, self.pos, (self.pos[0] + self.width, self.pos[1] + self.height),
                     (50, 50, 225), 4)
        cv.putText(frame, self.value, (self.pos[0] + 20, self.pos[1] + 50),
                   cv.FONT_HERSHEY_PLAIN, 2, (50, 50, 225), 2)

    def clickCheck(self, x, y, frame):
        if self.pos[0] < x < self.pos[0] + self.width and self.pos[1] < y < self.pos[1] + self.height:
            cv.rectangle(frame, self.pos, (self.pos[0] + self.width, self.pos[1] + self.height),
                         (255, 255, 225), cv.FILLED)
            cv.rectangle(frame, self.pos, (self.pos[0] + self.width, self.pos[1] + self.height),
                         (0, 0, 50), 4)
            cv.putText(frame, self.value, (self.pos[0] + 20, self.pos[1] + 50),
                       cv.FONT_HERSHEY_PLAIN, 2, (50, 50, 25), 6)
            return True
        return False

detect = HandDetector(detectionCon=0.9, maxHands=1)

butListVal = [
    ['1', '2', '3', '+'],
    ['4', '5', '6', '-'],
    ['7', '8', '9', '*'],
    ['0', '/', '.', '=']
]

butList = [Button((x * 100 + 800, y * 100 + 150), 100, 100, butListVal[y][x]) for x in range(4) for y in range(4)]

myEq = ""
delayCounter = 0
finEq = ""


def serve(frame):
    global myEq, delayCounter, finEq
    frame = cv.flip(frame, 1)

    hand, frame = detect.findHands(frame, flipType=False)

    cv.rectangle(frame, (800, 50), (1200, 150), (225, 255, 225), cv.FILLED)
    cv.rectangle(frame, (800, 50), (1200, 150), (50, 50, 225), 4)
    for button in butList:
        button.draw(frame)


    ev=""

    if hand:
        lmList = hand[0]['lmList']
        length, info, frame = detect.findDistance(lmList[8][:2], lmList[12][:2], frame)
        x, y = lmList[8][:2]

        if length < 35:
            for i, button in enumerate(butList):
                if button.clickCheck(x, y, frame) and delayCounter == 0:
                    myVal = butListVal[int(i % 4)][int(i / 4)]
                    if myVal == '=' and myEq != "":
                        finEq = str(eval(myEq))
                        ev=myEq+"="+finEq
                        myEq = ""
                    elif myVal != '=':
                        myEq += myVal
                        finEq = ""
                    delayCounter = 1

    if delayCounter != 0:
        delayCounter += 1
        if delayCounter > 10:
            delayCounter = 0

    display_text = finEq if myEq == "" else myEq
    cv.putText(frame, display_text, (820, 114), cv.FONT_HERSHEY_PLAIN, 3, (50, 50, 225), 3)
    if ev!="":
        return frame,ev
    else:
        return frame,""


================================================
FILE: requirements.txt
================================================
absl-py==2.1.0
attrs==23.2.0
blinker==1.8.2
cffi==1.16.0
click==8.1.7
colorama==0.4.6
contourpy==1.2.1
cvzone==1.6.1
cycler==0.12.1
Flask==3.0.3
Flask-Cors==4.0.1
flatbuffers==24.3.25
fonttools==4.53.0
gunicorn==22.0.0
importlib_metadata==8.0.0
importlib_resources==6.4.0
itsdangerous==2.2.0
jax==0.4.30
jaxlib==0.4.30
Jinja2==3.1.4
kiwisolver==1.4.5
MarkupSafe==2.1.5
matplotlib==3.9.1
mediapipe==0.10.14
ml-dtypes==0.4.0
numpy==2.0.0
opencv-contrib-python==4.10.0.84
opencv-python==4.10.0.84
opt-einsum==3.3.0
packaging==24.1
pillow==10.4.0
protobuf==4.25.3
pycparser==2.22
pyparsing==3.1.2
python-dateutil==2.9.0.post0
scipy==1.13.1
six==1.16.0
sounddevice==0.4.7
Werkzeug==3.0.3
zipp==3.19.2


================================================
FILE: static/serve.js
================================================
const processedVideo = document.getElementById('processed-video');

// Request access to the camera
navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {
        const videoTracks = stream.getVideoTracks();
        const track = videoTracks[0];
        const imageCapture = new ImageCapture(track);
        processFrames(imageCapture);
        

    })
    .catch(error => {
        console.error('Error accessing the camera: ', error);
    });

function processFrames(imageCapture) {
    const fps = 10; // Frames per second
    setInterval(() => {
        imageCapture.grabFrame()
            .then(imageBitmap => {
                const canvas = document.createElement('canvas');
                const context = canvas.getContext('2d');
                canvas.width = 1280;
                canvas.height = 900;
                context.drawImage(imageBitmap, 0, 0, canvas.width, canvas.height);
                canvas.toBlob(blob => {
                    const formData = new FormData();
                    formData.append('frame', blob, 'frame.jpg');
                    fetch('/process_frame', {
                        method: 'POST',
                        body: formData
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            // Display the processed frame
                            processedVideo.src = 'data:image/jpeg;base64,' + data.frame;
                        } else {
                            console.error('Error processing frame: ', data.message);
                        }
                    })
                    .catch(error => {
                        console.error('Error processing frame: ', error);
                    });
                }, 'image/jpeg');
            })
            .catch(error => {
                console.error('Error grabbing frame: ', error);
            });
    }, 1000 / fps);
}

function updateHisory(){
    fetch('/get_history').then(response => response.json()).then(data => {
        if (data.success) {
            const historyList = document.getElementById('history-list');
            console.log(data.history);
            historyList.innerHTML = '';
            data.history.forEach(item => {
                const listItem = document.createElement('li');
                listItem.textContent = item;
                historyList.appendChild(listItem);
            });
        } else {
            console.error('Error getting history: ', data.message);
        }
    }).catch(error => {
        console.error('Error getting history: ', error);
    });
}

setInterval(updateHisory, 2000);

================================================
FILE: templates/index.html
================================================
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    </head>
    <body class="bg-dark text-light">
        <header class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between py-3 mb-4 border-bottom mx-5 px-5 rounded ">
            <div class="col-md-3 mb-2 mb-md-0">
              <a href="/" class="d-inline-flex link-body-emphasis text-decoration-none">
                <svg class="bi" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"></use></svg>
              </a>
            </div>
      
            <div class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
              <h3 style="font-family:'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif " ><strong> Virtual Calculator </strong></h3>
            </div>
      
            <div class="col-md-3 text-end d-flex align-items-center justify-content-around">
                <p style="font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; margin: 0;">Connect with me:</p>
                <div class="d-flex gap-2">
                    <a href="https://www.linkedin.com/in/hazsyl1/">
                        <button type="button" class="btn btn-primary">LinkedIn</button>
                    </a>
                    <a href="https://github.com/HazSyl1">
                        <button type="button" class="btn btn-primary">GitHub</button>
                    </a>
                </div>
          </header>
          <main style="display: flex;flex-direction: column; justify-content: center; align-items: center; height: 100%; ">
            <!-- <img style="display: block;" src="{{url_for('video_function')}}" alt="Video Footage" width="50%" height="auto"> -->
            <!-- <video style="border:2px solid #333; border-radius: 8px; margin:10px;" id="video"  autoplay></video> -->
            <img id="processed-video" alt="Processed Frame"  width="50%" height="auto">
            <script src="{{ url_for('static',filename='serve.js') }}"></script>


          <p  style="font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; margin: 0;">Refresh to restart!</p>
          <div style="margin-top: 20px;">
            <ul id="history-list" style="list-style: none; padding-left: 0;">
              {% for item in history %}
                <li style="font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; margin: 0;">{{item}}</li>
              {% endfor %}
            </ul>
          </div>
          </main>
    </body>
</html>
Download .txt
gitextract_mpzxbp6l/

├── .gitignore
├── Dockerfile
├── README.md
├── app.py
├── main.py
├── requirements.txt
├── static/
│   └── serve.js
└── templates/
    └── index.html
Download .txt
SYMBOL INDEX (11 symbols across 3 files)

FILE: app.py
  function process_frame (line 46) | def process_frame():
  function update_history (line 68) | def update_history():
  function index (line 74) | def index():
  function video_function (line 80) | def video_function():

FILE: main.py
  class Button (line 4) | class Button:
    method __init__ (line 5) | def __init__(self, pos, width, height, value):
    method draw (line 11) | def draw(self, frame):
    method clickCheck (line 19) | def clickCheck(self, x, y, frame):
  function serve (line 46) | def serve(frame):

FILE: static/serve.js
  function processFrames (line 17) | function processFrames(imageCapture) {
  function updateHisory (line 54) | function updateHisory(){
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (13K chars).
[
  {
    "path": ".gitignore",
    "chars": 9,
    "preview": "/virtualC"
  },
  {
    "path": "Dockerfile",
    "chars": 367,
    "preview": "FROM python:3.9-slim \n\nWORKDIR /\nCOPY . .\nRUN apt-get update && apt-get install ffmpeg libsm6 libxext6  -y\nRUN apt-get u"
  },
  {
    "path": "README.md",
    "chars": 91,
    "preview": "A virtual calculator build using OpenCV.\nDEMO: https://www.youtube.com/watch?v=M8ZjUq8QD10\n"
  },
  {
    "path": "app.py",
    "chars": 2055,
    "preview": "from flask import Flask,render_template,Response, jsonify , request\nimport cv2 as cv \nfrom main import serve\nimport nump"
  },
  {
    "path": "main.py",
    "chars": 3102,
    "preview": "import cv2 as cv\r\nfrom cvzone.HandTrackingModule import HandDetector\r\n\r\nclass Button:\r\n    def __init__(self, pos, width"
  },
  {
    "path": "requirements.txt",
    "chars": 696,
    "preview": "absl-py==2.1.0\nattrs==23.2.0\nblinker==1.8.2\ncffi==1.16.0\nclick==8.1.7\ncolorama==0.4.6\ncontourpy==1.2.1\ncvzone==1.6.1\ncyc"
  },
  {
    "path": "static/serve.js",
    "chars": 2709,
    "preview": "const processedVideo = document.getElementById('processed-video');\n\n// Request access to the camera\nnavigator.mediaDevic"
  },
  {
    "path": "templates/index.html",
    "chars": 3031,
    "preview": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
  }
]

About this extraction

This page contains the full source code of the HazSyl1/Virtual_Calculator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (11.8 KB), approximately 3.4k tokens, and a symbol index with 11 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!