An easy to use an (hopefully useful) captcha solution for pyTelegramBotAPI

Overview

pyTelegramBotCAPTCHA

An easy to use and (hopefully useful) image CAPTCHA soltion for pyTelegramBotAPI.

PyPi Package Version Supported Python versions


Installation:

pip install pyTelegramBotCAPTCHA

Do not forget to update the package from time to time by calling
pip install pyTelegramBotCAPTCHA --upgrade


Description:

Do you have problems with userbots that spam your groups or add your group members to other chats? Then this package can help you to protect your groups and members! It's very easy to integrate into your existing bot and also easy to customize the CAPTCHA image with your own fonts.
You can also choose between digits and hexdigits for your CAPTCHA generation.
Note: You should have basic knowledge about the pyTelegramBotAPI
Example1 Example2


Writing a CAPTCHA bot:

Import TeleBot and the CapchaManager:

from telebot import TeleBot
from pyTelegramBotCAPTCHA import CaptchaManager

Initialize the bot and the captcha_manager:

CaptchaManager requires the user_id of your TeleBot instance! You get it with bot.get_me().id
You can add the following optional parameters:

  • default_language (str) the default language to use if not set in captcha_manager.send_random_captcha(...). Default is "en". Currently supported "en", "ru" and "de"
  • default_timeout (float) the default timeout to use if not set in captcha_manager.send_random_captcha(...). Default is None but we will use a default_timeout of 90 seconds for our CAPTCHAs.
  • fonts (list) the fonts to use instead of the builtin ones (must be a list of .ttf file paths). You can choose as many fonts as you like, but keep in mind that all the fonts are loaded into your memory, so use a lot but not to many.
bot = TeleBot("TOKEN")
captcha_manager = CaptchaManager(bot.get_me().id, default_timeout=90)

Note: Make sure to actually replace TOKEN with your own API token


Add a message handler for new chat members:

We need a message handler to restrict the new member and sending a CAPTCHA to solve when a new user joins the group.
captcha_manager.restrict_chat_member() requires your TeleBot instance, the chat_id and the user_id. It disables all permissions of a chat member.
captcha_manager.send_random_captcha() requires your TeleBot instance, the Chat object and the User object. It sends a new CAPTCHA in the chat.
You can add the following optional parameters:

  • language (str) the language to use for this CAPTCHA
  • add_noise (bool) add noise to the CAPTCHA image
  • only_digits (bool) only use ditgits instead of hexdigits for the CAPTCHA code
  • timeout (float) to set a timeout for the CAPTCHA in seconds.
# Message handler for new chat members
@bot.message_handler(content_types=["new_chat_members"])
def new_member(message):
  # get the new chat members
  for user in message.new_chat_members:

    # Restrict the new chat member
    captcha_manager.restrict_chat_member(bot, message.chat.id, user.id)

    # send random CAPTCHA
    captcha_manager.send_random_captcha(bot, message.chat, user)

Note: Service messages about non-bot users joining the chat will be soon removed from large groups. We recommend using the “chat_member” update as a replacement.


Add a callback query handler:

We need a callback query handler, to handle the users input when he presses a CAPTCHA button.
captcha_manager.update_captcha() requires your TeleBot instance and the CallbackQuery object as parameters.
It automatically returns if callback was not from a CAPTCHA or from the wrong user.
If the wrong user pressed a button he gets an callback query answer denying his input.
If the submit button is pressed the CAPTCHA is automatically checked and your corresponding CAPTCHA handler function is called. The timeout is also canceled if submit is pressed.

# Callback query handler
@bot.callback_query_handler(func=lambda callback:True)
def on_callback(callback):
  # update the CAPTCHA
  captcha_manager.update_captcha(bot, callback)

Add CAPTCHA handler functions:

This works just like you know it from message handlers from the pyTelegramBotAPI.
A Captcha object will be passed to your functions.
The Captcha object has the following attributes:

  • message_id (int) the message id of the CAPTCHA message
  • user (User) the user that must solve the CAPTCHA
  • chat (Chat) the chat
  • users_code (str) the code entered by the user
  • correct_code (str) the correct code to solve the CAPTCHA
  • language (str) the language of the CAPTCHA text
  • created_at (float) the timestemp when the CAPTCHA was created
  • previous_tries (int) the number of tries the user made
  • incorrect_digits (int) the number of digits that dont match
  • solved (bool) has the user solved the CAPTCHA? it does not matter if he solved it correct

Lets add our first CAPTCHA handler that handles correct solved CAPTCHAs. captcha_manager.unrestrict_chat_member() requires your TeleBot instance, the chat_id and the user_id. It removes all restictions of a chat member.
captcha_manager.delete_captcha() requires your TeleBot instance and the Captcha object. It removes the CAPTCHA from the chat and your memory

# Handler for correct solved CAPTCHAs
@captcha_manager.on_captcha_correct
def on_correct(captcha):
  bot.send_message(captcha.chat.id, "Congrats! You solved the CAPTCHA!")
  # We unrestrict the chat member because he solved the CAPTCHA correct.
  captcha_manager.unrestrict_chat_member(bot, captcha.chat.id, captcha.user.id)
  # Delete the CAPTCHA
  captcha_manager.delete_captcha(bot, captcha)

Lets add a handler that handles wrong solved CAPTCHAs.
We use the Captcha attributes incorrect_digits and previous_tries to give the user a second try if only one digit was incorrect.
captcha_manager.refresh_captcha() requires your TeleBot instance and the Captcha object. It generates a new code image.
You can add the following optional parameters:

  • add_noise (bool) add noise to the CAPTCHA image
  • only_digits (bool) only use ditgits instead of hexdigits for the CAPTCHA code
  • timeout (float) set new timeout because the previous is canceled. If not set it will captcha_manager.default_timeout (if set).
# Handler for wrong solved CAPTCHAs
@captcha_manager.on_captcha_not_correct
def on_not_correct(captcha):
  # Check if only one dicit was incorrect and the user only did one try
  if (captcha.incorrect_digits == 1 and captcha.previous_tries < 2):
    # Refresh the CAPTCHA
    captcha_manager.refresh_captcha(bot, captcha)
  else:
    # We ban the chat member because he failed solving the CAPTCHA.
    bot.kick_chat_member(captcha.chat.id, captcha.user.id)
    bot.send_message(captcha.chat.id, f"{captcha.user.first_name} failed solving the CAPTCHA and was banned!")
    # Delete the CAPTCHA
    captcha_manager.delete_captcha(bot, captcha)

Now lets add a handler that handles timed out CAPTCHAs

# Handler for timed out CAPTCHAS
@captcha_manager.on_captcha_timeout
def on_timeout(captcha):
  # We ban the chat member because he did not solve the CAPTCHA.
  bot.kick_chat_member(captcha.chat.id, captcha.user.id)
  bot.send_message(captcha.chat.id, f"{captcha.user.first_name} did not solve the CAPTCHA and was banned!")
  # Delete the CAPTCHA
  captcha_manager.delete_captcha(bot, captcha)

The finished CAPTCHA bot

Now we only have to add the line bot.polling()at the end of our script and we have a finished CAPTCHA bot that looks like this:

from telebot import TeleBot
from pyTelegramBotCAPTCHA import CaptchaManager
                                                                    
bot = TeleBot("TOKEN")
captcha_manager = CaptchaManager(bot.get_me().id)

# Message handler for new chat members
@bot.message_handler(content_types=["new_chat_members"])
def new_member(message):
  new_user_id = message.json.get("new_chat_member").get("id")
  new_user = bot.get_chat_member(message.chat.id, new_user_id).user
  captcha_manager.restrict_chat_member(bot, message.chat.id, new_user.id)
  captcha_manager.send_random_captcha(bot, message.chat, new_user)
                                                                    
# Callback query handler
@bot.callback_query_handler(func=lambda callback:True)
def on_callback(callback):
  captcha_manager.update_captcha(bot, callback)
                                                                    
# Handler for correct solved CAPTCHAs
@captcha_manager.on_captcha_correct
def on_correct(captcha):
  bot.send_message(captcha.chat.id, "Congrats! You solved the CAPTCHA!")
  captcha_manager.unrestrict_chat_member(bot, captcha.chat.id, captcha.user.id)
  captcha_manager.delete_captcha(bot, captcha)

# Handler for wrong solved CAPTCHAs
@captcha_manager.on_captcha_not_correct
def on_not_correct(captcha):
  if (captcha.incorrect_digits == 1 and captcha.previous_tries < 2):
    captcha_manager.refresh_captcha(bot, captcha)
  else:
    bot.kick_chat_member(captcha.chat.id, captcha.user.id)
    bot.send_message(captcha.chat.id, f"{captcha.user.first_name} failed solving the CAPTCHA and was banned!")
    captcha_manager.delete_captcha(bot, captcha)
  
# Handler for timed out CAPTCHAS
@captcha_manager.on_captcha_timeout
def on_timeout(captcha):
  bot.kick_chat_member(captcha.chat.id, captcha.user.id)
  bot.send_message(captcha.chat.id, f"{captcha.user.first_name} did not solve the CAPTCHA and was banned!")
  captcha_manager.delete_captcha(bot, captcha)
  
bot.polling()
Comments
  • Issues with CustomLanguage parameters 'your_code' and 'try_again'

    Issues with CustomLanguage parameters 'your_code' and 'try_again'

    Let's take the following setup:

    languages = CustomLanguage() languages.text = "text" languages.try_again = "again" languages.wrong_user = "wrong" languages.too_short = "short" languages.your_code = "code"

    'try_again' is actually not shown when it should. You keep seeing 'text' on both a wrong attempt and a manual user refresh.

    'your_code' is also not shown when it should. You always see the default "Your Code:", and 'your_code' does show up but only on a wrong attempt or a manual user refresh (it is not visible on the initial captcha). However, "Your Code:" is still visible up to this point, so you actually see two lines, one time the default one, and one time the new custom one.

    bug 
    opened by tinderboxmedia 5
  • Inconsistency: A captcha reload on an incorrect submit has default values

    Inconsistency: A captcha reload on an incorrect submit has default values

    If an individual fails to solve the captcha and if another attempt is allowed, the captcha will refresh but it will override variables such as timeout, digits_only and add_noice. This feels like an inconsistency in the logic as a refresh should give a new captcha but with all the user declared variables and values. If the function is declared to not add_noice or to be digits_only, a refresh should not change this behaviour, unless declared otherwise.

    To fix this inconsistency the captcha refresh should either follow the user declared variables and values, or one should be able to allow this override to happen or not.

    enhancement 
    opened by tinderboxmedia 5
  • No timeout anymore when user has made a wrong attempt

    No timeout anymore when user has made a wrong attempt

    There seems to be an error where there is no timeout event anymore when a user made a wrong attempt, it also seems to not work anymore when a user manually refreshed the CAPTCHA. It still happens though when a user is still on the initial CAPTCHA. I tried this with the default timeout of 90, and a custom timeout. Note that max_incorrect_to_auto_reload has been set to 1, so a timeout should still happen.

    bug 
    opened by tinderboxmedia 4
  • Suggestion: Be able to declare the digits and hex-digits used in the captcha outside of the module

    Suggestion: Be able to declare the digits and hex-digits used in the captcha outside of the module

    Currently the only way to change the digits and hex-digits used in the captcha is to change variables inside of the module. The suggestion would be to be able to declare which digits or letters can be used, but still in a set of 10 (the 2 by 5 input markup grid), or a set of 16 (the 4x4 input markup grid).

    The main reason for this suggestion is that some fonts do have characters that could potentially look to similar. For example: 8 and B, or 1 and 7. Be able to declare a custom set of 10 or 16 characters, the captchas could become more user friendly but still bot proof.

    opened by tinderboxmedia 4
  • Suggestion: Be able to declare the length of the captcha

    Suggestion: Be able to declare the length of the captcha

    Currently the length of the captcha showed is defaulted and hardcoded to be 8 characters long. The suggestion would be to be able to declare the length of the captcha, so that it can display less or even more characters that need to be solved.

    enhancement 
    opened by tinderboxmedia 4
  • KeyZenD returns a 404. Fallback to 'Default' might be needed.

    KeyZenD returns a 404. Fallback to 'Default' might be needed.

    Seems like the KeyZenD CAPTCHA can't be found anymore: https://tyt.xyeta.ml/captcha.png

    This page returns an 404, and the CAPTCHA can't be found. Maybe it would be smart to add some sort of fallback that turns the option back to 'default' as currently this would break the entire thing?

    opened by tinderboxmedia 3
  • Issue: Adding 1+ users to the channel will only trigger 1 captcha

    Issue: Adding 1+ users to the channel will only trigger 1 captcha

    After some more stress testing it seems to be the case that if someone invites or adds more than 1 user (the option to mass invite your contacts to a channel for example) to the channel where the bot is active, it will only create 1 captcha. Only one user has to complete the captcha, the other users are already 'in' (so to speak).

    opened by tinderboxmedia 3
  • ERROR: TypeError: 'float' object cannot be interpreted as an integer

    ERROR: TypeError: 'float' object cannot be interpreted as an integer

    I try init a new bot with

    from telebot import TeleBot
    from pyTelegramBotCAPTCHA import CaptchaManager
                                                                        
    bot = TeleBot("MY_TOKEN")
    captcha_manager = CaptchaManager(bot.get_me().id)
    
    # Message handler for new chat members
    @bot.message_handler(content_types=["new_chat_members"])
    def new_member(message):
      for new_user in message.new_chat_members:
        captcha_manager.restrict_chat_member(bot, message.chat.id, new_user.id)
        captcha_manager.send_new_captcha(bot, message.chat, new_user)
                                                                        
    # Callback query handler
    @bot.callback_query_handler(func=lambda callback:True)
    def on_callback(callback):
      captcha_manager.update_captcha(bot, callback)
                                                                        
    # Handler for correct solved CAPTCHAs
    @captcha_manager.on_captcha_correct
    def on_correct(captcha):
      bot.send_message(captcha.chat.id, "Congrats! You solved the CAPTCHA!")
      captcha_manager.unrestrict_chat_member(bot, captcha.chat.id, captcha.user.id)
      captcha_manager.delete_captcha(bot, captcha)
    
    # Handler for wrong solved CAPTCHAs
    @captcha_manager.on_captcha_not_correct
    def on_not_correct(captcha):
      if (captcha.incorrect_digits == 1 and captcha.previous_tries < 2):
        captcha_manager.refresh_captcha(bot, captcha)
      else:
        bot.kick_chat_member(captcha.chat.id, captcha.user.id)
        bot.send_message(captcha.chat.id, f"{captcha.user.first_name} failed solving the CAPTCHA and was banned!")
        captcha_manager.delete_captcha(bot, captcha)
    
    # Handler for timed out CAPTCHAS
    @captcha_manager.on_captcha_timeout
    def on_timeout(captcha):
      bot.kick_chat_member(captcha.chat.id, captcha.user.id)
      bot.send_message(captcha.chat.id, f"{captcha.user.first_name} did not solve the CAPTCHA and was banned!")
      captcha_manager.delete_captcha(bot, captcha)
      
    bot.polling()
    

    And i take a error:

    Traceback (most recent call last):
      File "/Users/olivmath/repo/lunes/bot-telegram-cruzeiro/olivmath.py", line 43, in <module>
        bot.polling()
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/telebot/__init__.py", line 660, in polling
        self.__threaded_polling(non_stop, interval, timeout, long_polling_timeout, allowed_updates)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/telebot/__init__.py", line 722, in __threaded_polling
        raise e
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/telebot/__init__.py", line 682, in __threaded_polling
        self.worker_pool.raise_exceptions()
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/telebot/util.py", line 135, in raise_exceptions
        raise self.exception_info
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/telebot/util.py", line 87, in run
        task(*args, **kwargs)
      File "/Users/olivmath/repo/lunes/bot-telegram-cruzeiro/olivmath.py", line 12, in new_member
        captcha_manager.send_new_captcha(bot, message.chat, new_user)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/pyTelegramBotCAPTCHA/telebot_captcha.py", line 553, in send_new_captcha
        captcha = Captcha(bot, chat, user, options)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/pyTelegramBotCAPTCHA/telebot_captcha.py", line 345, in __init__
        self.correct_code, self.image = _random_codeimage(self.options)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/pyTelegramBotCAPTCHA/telebot_captcha.py", line 865, in _random_codeimage
        image = image.generate_image(code)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/captcha/image.py", line 228, in generate_image
        im = self.create_captcha_image(chars, color, background)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/captcha/image.py", line 212, in create_captcha_image
        mask = im.convert('L').point(table)
      File "/Users/olivmath/Library/Caches/pypoetry/virtualenvs/bot-telegram-cruzeiro-rcJnbm2r-py3.10/lib/python3.10/site-packages/PIL/Image.py", line 1680, in point
        return self._new(self.im.point(lut, mode))
    TypeError: 'float' object cannot be interpreted as an integer
    
    opened by olivmath 2
  • Refresh button

    Refresh button

    Hi there,

    Great work - loving your captcha bot! I had one idea that would be great to implement. A Refresh button in case the captcha is really hard / barley readable.

    Keep it up!

    enhancement good first issue 
    opened by fabston 2
  • Issue: Adding the code_length argument to send_random_captcha will throw a TypeError.

    Issue: Adding the code_length argument to send_random_captcha will throw a TypeError.

    For example, trying initialize the captcha using captcha_manager.send_random_captcha(bot, message.chat, new_user, timeout=60, code_length=4, language="en") will result in TypeError: send_random_captcha() got an unexpected keyword argument 'code_length'

    However, following the documentation this should be possible.

    opened by tinderboxmedia 2
  • Issue: If a captcha is not properly removed after kicking a user, it will throw a KeyError when trying to interact with it again

    Issue: If a captcha is not properly removed after kicking a user, it will throw a KeyError when trying to interact with it again

    While interacting with a captcha button (update_captcha), it should first be checked if that captcha session is still 'available' or not. It not being 'available' can be due to that the captcha message was not deleted properly after kicking a user and that user did not solve it, or that the file that holds that captcha session is somehow removed.

    Right now it will throw a KeyError if the session can't be found, but if we can check if that captcha session is not available anymore, we could just remove the captcha instead (whoever presses it) and clean up.

    opened by tinderboxmedia 2
Releases(1.1.4)
TedEval: A Fair Evaluation Metric for Scene Text Detectors

TedEval: A Fair Evaluation Metric for Scene Text Detectors Official Python 3 implementation of TedEval | paper | slides Chae Young Lee, Youngmin Baek,

Clova AI Research 167 Nov 20, 2022
Document blur detection based on Laplacian operator and text detection.

Document Blur Detection For general blurred image, using the variance of Laplacian operator is a good solution. But as for the blur detection of docum

JoeyLr 5 Oct 20, 2022
Use Convolutional Recurrent Neural Network to recognize the Handwritten line text image without pre segmentation into words or characters. Use CTC loss Function to train.

Handwritten Line Text Recognition using Deep Learning with Tensorflow Description Use Convolutional Recurrent Neural Network to recognize the Handwrit

sushant097 224 Jan 07, 2023
Creating a virtual tv using opencv in python3.

Virtual-TV Creating a virtual tv using opencv in python3. In order to run the code follow the below given steps: Make sure the desired videos which ar

Vamsi 1 Jan 01, 2022
Motion Detection Squid Game with OpenCV Python

*Motion Detection Squid Game with OpenCV Python i am newbie in python. In this project I made a simple game to follow the trend about the red light gr

Nayan 17 Nov 22, 2022
Camera Intrinsic Calibration and Hand-Eye Calibration in Pybullet

This repository is mainly for camera intrinsic calibration and hand-eye calibration. Synthetic experiments are conducted in PyBullet simulator. 1. Tes

CAI Junhao 7 Oct 03, 2022
Natural language detection

Detect the language of text. What’s so cool about franc? franc can support more languages(†) than any other library franc is packaged with support for

Titus 3.8k Jan 02, 2023
第一届西安交通大学人工智能实践大赛(2018AI实践大赛--图片文字识别)第一名;仅采用densenet识别图中文字

OCR 第一届西安交通大学人工智能实践大赛(2018AI实践大赛--图片文字识别)冠军 模型结果 该比赛计算每一个条目的f1score,取所有条目的平均,具体计算方式在这里。这里的计算方式不对一句话里的相同文字重复计算,故f1score比提交的最终结果低: - train val f1score 0

尹畅 441 Dec 22, 2022
Zoom , GoogleMeets에서 Vtuber 데뷔하기

EasyVtuber Facial landmark와 GAN을 이용한 Character Face Generation Google Meets, Zoom 등에서 자신만의 웹툰, 만화 캐릭터로 대화해보세요! 악세사리는 어느정도 추가해도 잘 작동해요! 안타깝게도 RTX 2070

Gunwoo Han 140 Dec 23, 2022
Textboxes : Image Text Detection Model : python package (tensorflow)

shinTB Abstract A python package for use Textboxes : Image Text Detection Model implemented by tensorflow, cv2 Textboxes Paper Review in Korean (My Bl

Jayne Shin (신재인) 91 Dec 15, 2022
This repository contains the code for the paper "SCANimate: Weakly Supervised Learning of Skinned Clothed Avatar Networks"

SCANimate: Weakly Supervised Learning of Skinned Clothed Avatar Networks (CVPR 2021 Oral) This repository contains the official PyTorch implementation

Shunsuke Saito 235 Dec 18, 2022
Face Recognizer using Opencv Python

Face Recognizer using Opencv Python The first step create your own dataset with file open-cv-create_dataset second step You can put the photo accordin

Han Izza 2 Nov 16, 2021
Detect textlines in document images

Textline Detection Detect textlines in document images Introduction This tool performs border, region and textline detection from document image data

QURATOR-SPK 70 Jun 30, 2022
Pre-Recognize Library - library with algorithms for improving OCR quality.

PRLib - Pre-Recognition Library. The main aim of the library - prepare image for recogntion. Image processing can really help to improve recognition q

Alex 80 Dec 30, 2022
Some Boring Research About Products Recognition 、Duplicate Img Detection、Img Stitch、OCR

Products Recognition 介绍 商品识别,围绕在复杂的商场零售场景中,识别出货架图像中的商品信息。主要组成部分: 重复图像检测。【更新进度 4/10】 图像拼接。【更新进度 0/10】 目标检测。【更新进度 0/10】 商品识别。【更新进度 1/10】 OCR。【更新进度 1/10】

zhenjieWang 18 Jan 27, 2022
Responsive Doc. scanner using U^2-Net, Textcleaner and Tesseract

Responsive Doc. scanner using U^2-Net, Textcleaner and Tesseract Toolset U^2-Net is used for background removal Textcleaner is used for image cleaning

3 Jul 13, 2022
A small C++ implementation of LSTM networks, focused on OCR.

clstm CLSTM is an implementation of the LSTM recurrent neural network model in C++, using the Eigen library for numerical computations. Status and sco

Tom 794 Dec 30, 2022
MeshToGeotiff - A fast Python algorithm to convert a 3D mesh into a GeoTIFF

MeshToGeotiff - A fast Python algorithm to convert a 3D mesh into a GeoTIFF Python class for converting (very fast) 3D Meshes/Surfaces to Raster DEMs

8 Sep 10, 2022
A facial recognition device is a device that takes an image or a video of a human face and compares it to another image faces in a database.

A facial recognition device is a device that takes an image or a video of a human face and compares it to another image faces in a database. The structure, shape and proportions of the faces are comp

Pavankumar Khot 4 Mar 19, 2022
【Auto】原神⭐钓鱼辅助工具 | 自动收竿、校准游标 | ✨您只需要抛出鱼竿,我们会帮你完成一切✨

原神钓鱼辅助工具 ✨ 作者正在努力重构代码中……会尽快带给大家一个更完美的脚本 ✨ 「您只需抛出鱼竿,然后我们会帮您搞定一切」 如果你觉得这个脚本好用,请点一个 Star ⭐ ,你的 Star 就是作者更新最大的动力 点击这里 查看演示视频 ✨ 欢迎大家在 Issues 中分享自己的配置文件 ✨ ✨

261 Jan 02, 2023