1680195840
Плавающие запятые в JavaScript имеют чрезвычайно высокую точность, и вам не всегда нужна эта точность. Кроме того, ваш пользователь еще меньше захочет этого. Чаще всего мы хотим «обрезать» числа с плавающей запятой, установив определенную точность (например, два десятичных знака) для конечного пользователя.
У объекта Numberесть несколько методов, которые позволяют нам изменить точность числа с плавающей запятой в JavaScript!
toFixed()это Numberметод, который используется для преобразования числа в запись с фиксированной точкой ( при необходимости округление результата ) и возвращает значение в виде строки:
number.toFixed([decimalPlaces]);
decimalPlacesявляется необязательным и определяет количество цифр, которые должны присутствовать после десятичной точки, и по умолчанию 0:
let number = 12345.6789
console.log(number.toFixed()) // Returns '12346': note rounding, no fractional part
console.log(number.toFixed(1)) // Returns '12345.7': note rounding
console.log(number.toFixed(6)) // Returns '12345.678900': note added zeros
console.log((1.23e+20).toFixed(3)) // Returns '123000000000000000000.000'
Если число с плавающей запятой не обеспечивает точности до фиксированной точки, которую вы форматируете, 0 добавляются в качестве дополнения в конец.
toPrecision()это Numberметод, который форматирует число в строку точности - отслеживая, сколько всего цифр (включая цифры слева и справа от десятичной дроби) для отображения числа:
number.toPrecision([significantDigits]);
significantDigitsявляется необязательным, обозначая количество значащих цифр для отображения в результате. Если он опущен, метод просто преобразует число в строку.
let number = 5.123456
console.log(number.toPrecision()) // logs '5.123456'
console.log(number.toPrecision(5)) // logs '5.1235'
number = 0.000123
console.log(number.toPrecision()) // logs '0.000123'
console.log(number.toPrecision(5)) // logs '0.00012300'
Возвращаемые значения имеют stringтип:
console.log(typeof number.toPrecision()) // string
Примечание. Метод toPrecision()дополняет результирующее значение нулями, если не хватает значащих цифр, и не изменяет значение исходного числа — он возвращает новый результат.
Функция toExponential()в JavaScript используется для отображения числа в экспоненциальной записи (иногда называемой экспоненциальной записью ), даже если число находится внутри диапазона, в котором JavaScript обычно использует стандартную запись:
number.toExponential([fractionalDigits]);
Примечание. Стоит отметить, что при достаточно малых и достаточно больших числах JavaScript автоматически отображает их в их экспоненциальной записи.
fractionalDigitsв качестве аргумента является необязательным и указывает, сколько цифр дробной части должно отображаться в результате. Если этот аргумент отсутствует, выходные данные могут содержать до 16 дробных цифр, в зависимости от вашего браузера:
let number = 95.3434;
console.log(number.toExponential()); // 9.53434e+1
console.log(number.toExponential(4)); // 9.5343e+1
console.log(number.toExponential(2)); // 9.53e+1
console.log(95.3434.toExponential()); // 9.53434e+1
Примечание. Метод toExponential()не изменяет значение исходного числа — он возвращает новое значение для сохранения.
В этом кратком руководстве мы рассмотрели процесс установки точности для чисел с плавающей запятой в JavaScript с использованием методов toExponential()и toFixed()методов toPrecision()объекта Number.
Оригинальный источник статьи по адресу: https://stackabuse.com/
1680192060
JavaScript 中的浮点数具有极高的精度,您并不总是需要这种精度。此外 - 您的用户更不可能想要它。通常情况下 - 我们希望通过为最终用户设置特定精度(例如,两位小数)来“修剪”浮点数。
该Number对象有几个方法可以让我们改变 JavaScript 中浮点数的精度!
toFixed()是一种Number用于将数字转换为定点表示法(必要时对结果进行四舍五入)并将值作为字符串返回的方法:
number.toFixed([decimalPlaces]);
decimalPlaces是可选的,并定义小数点后应出现的位数,默认为0:
let number = 12345.6789
console.log(number.toFixed()) // Returns '12346': note rounding, no fractional part
console.log(number.toFixed(1)) // Returns '12345.7': note rounding
console.log(number.toFixed(6)) // Returns '12345.678900': note added zeros
console.log((1.23e+20).toFixed(3)) // Returns '123000000000000000000.000'
如果浮点数没有提供达到您要格式化为的定点的精度 - 0 将作为填充添加到末尾。
toPrecision()是一种Number将数字格式化为精度字符串的方法- 跟踪要显示数字的总位数(包括小数点左右的数字):
number.toPrecision([significantDigits]);
significantDigits是可选的,表示要在结果中显示的有效位数。如果省略,该方法只是将数字转换为字符串。
let number = 5.123456
console.log(number.toPrecision()) // logs '5.123456'
console.log(number.toPrecision(5)) // logs '5.1235'
number = 0.000123
console.log(number.toPrecision()) // logs '0.000123'
console.log(number.toPrecision(5)) // logs '0.00012300'
返回值的string类型:
console.log(typeof number.toPrecision()) // string
注意:toPrecision()如果没有足够的有效数字,该方法将用 0 填充结果值,并且它不会更改原始数字的值 - 它返回一个新结果。
JavaScript 中的函数toExponential()用于以指数计数法(有时称为科学计数法)显示数字,即使该数字在 JavaScript 通常使用标准计数法的范围内:
number.toExponential([fractionalDigits]);
注意:值得注意的是,对于足够小和足够大的数字,JavaScript 会自动以指数表示法显示它们。
fractionalDigits作为参数是可选的,并指定要在结果中显示多少小数位。如果缺少此参数,则输出最多可能包含 16 个小数位,具体取决于您的浏览器:
let number = 95.3434;
console.log(number.toExponential()); // 9.53434e+1
console.log(number.toExponential(4)); // 9.5343e+1
console.log(number.toExponential(2)); // 9.53e+1
console.log(95.3434.toExponential()); // 9.53434e+1
注意:该toExponential()方法不会更改原始数字的值 - 它会返回一个要存储的新值。
在这个简短的教程中,我们介绍了使用 对象的 和toExponential()方法在JavaScript 中设置浮点数精度的过程。toFixed()toPrecision()Number
原始文章来源:https: //stackabuse.com/
1680163080
Floating-points in JavaScript have an extremely high precision, and you don't always need this precision. Additionally - your user is even less likely to want it. More often than not - we'll want to "trim" floating-point numbers by setting a specific precision (such as, say, two decimal points) for an end-user.
The Number
object has several methods that allow us to change the precision of a floating-point number in JavaScript!
toFixed()
is a Number
method that is used to convert a number to fixed-point notation (rounding the result where necessary) and returns the value as a string:
number.toFixed([decimalPlaces]);
decimalPlaces
is optional, and defines the number of digits that should be present after the decimal place and defaults to 0
:
let number = 12345.6789
console.log(number.toFixed()) // Returns '12346': note rounding, no fractional part
console.log(number.toFixed(1)) // Returns '12345.7': note rounding
console.log(number.toFixed(6)) // Returns '12345.678900': note added zeros
console.log((1.23e+20).toFixed(3)) // Returns '123000000000000000000.000'
If the floating-point number didn't offer precision up to the fixed point you're formatting to - 0s are added as padding to the end.
toPrecision()
is a Number
method that formats a number to a precision string - keeping track of how many total digits (including digits to the left and right of the decimal) to display of a number:
number.toPrecision([significantDigits]);
significantDigits
is optional, denoting the number of significant digits to display in the result. If omitted, the method just converts the number to a string.
let number = 5.123456
console.log(number.toPrecision()) // logs '5.123456'
console.log(number.toPrecision(5)) // logs '5.1235'
number = 0.000123
console.log(number.toPrecision()) // logs '0.000123'
console.log(number.toPrecision(5)) // logs '0.00012300'
The returned values are of string
type:
console.log(typeof number.toPrecision()) // string
Note: The toPrecision()
method will pad the resulting value with 0's if there are not enough significant digits, and it does not change the value of the original number - it returns a new result.
The toExponential()
function in JavaScript is used to show a number in exponential notation (sometimes known as scientific notation), even if the number is inside the range where JavaScript ordinarily uses standard notation:
number.toExponential([fractionalDigits]);
Note: It's worth noting that with sufficiently small and sufficiently large numbers - JavaScript automatically displays them in their exponential notation.
fractionalDigits
as an argument is optional, and specifies how many fractional digits are to be displayed in the result. If this argument is missing, the output may contain up to 16 fractional digits, depending on your browser:
let number = 95.3434;
console.log(number.toExponential()); // 9.53434e+1
console.log(number.toExponential(4)); // 9.5343e+1
console.log(number.toExponential(2)); // 9.53e+1
console.log(95.3434.toExponential()); // 9.53434e+1
Note: The toExponential()
method does not change the value of the original number - it returns a new value to be stored.
In this short tutorial, we've covered the process of setting a precision for floating-point numbers in JavaScript, using the toExponential()
, toFixed()
and toPrecision()
methods of the Number
object.
Original article source at: https://stackabuse.com/
1679631240
Typst is a new markup-based typsetting system that is designed to be as powerful as LaTeX while being much easier to learn and use. Typst has:
This repository contains the Typst compiler and its CLI, which is everything you need to compile Typst documents locally. For the best writing experience, consider signing up to our collaborative online editor for free. It is currently in public beta.
A gentle introduction to Typst is available in our documentation. However, if you want to see the power of Typst encapsulated in one image, here it is:
Let's dissect what's going on:
We use set rules to configure element properties like the size of pages or the numbering of headings. By setting the page height to auto
, it scales to fit the content. Set rules accommodate the most common configurations. If you need full control, you can also use show rules to completely redefine the appearance of an element.
We insert a heading with the = Heading
syntax. One equals sign creates a top level heading, two create a subheading and so on. Typst has more lightweight markup like this, see the syntax reference for a full list.
Mathematical equations are enclosed in dollar signs. By adding extra spaces around the contents of a equation, we can put it into a separate block. Multi-letter identifiers are interpreted as Typst definitions and functions unless put into quotes. This way, we don't need backslashes for things like floor
and sqrt
. And phi.alt
applies the alt
modifier to the phi
to select a particular symbol variant.
Now, we get to some scripting. To input code into a Typst document, we can write a hashtag followed by an expression. We define two variables and a recursive function to compute the n-th fibonacci number. Then, we display the results in a center-aligned table. The table function takes its cells row-by-row. Therefore, we first pass the formulas $F_1$
to $F_10$
and then the computed fibonacci numbers. We apply the spreading operator (..
) to both because they are arrays and we want to pass the arrays' items as individual arguments.
Text version of the code example.
#set page(width: 10cm, height: auto)
#set heading(numbering: "1.")
= Fibonacci sequence
The Fibonacci sequence is defined through the
_recurrence relation_ $F_n = F_(n-1) + F_(n-2)$.
It can also be expressed in closed form:
$ F_n = floor(1 / sqrt(5) phi.alt^n), quad
phi.alt = (1 + sqrt(5)) / 2 $
#let count = 10
#let nums = range(1, count + 1)
#let fib(n) = (
if n <= 2 { 1 }
else { fib(n - 1) + fib(n - 2) }
)
The first #count numbers of the sequence are:
#align(center, table(
columns: count,
..nums.map(n => $F_#n$),
..nums.map(n => str(fib(n))),
))
You can get sources and pre-built binaries for the latest release of Typst from the releases page. This will give you Typst's CLI which converts Typst sources into PDFs.
# Creates `file.pdf` in working directory.
typst file.typ
# Creates PDF file at the desired path.
typst path/to/source.typ path/to/output.pdf
You can also watch source files and automatically recompile on changes. This is faster than compiling from scratch each time because Typst has incremental compilation.
# Watches source files and recompiles on changes.
typst --watch file.typ
If you prefer an integrated IDE-like experience with autocompletion and instant preview, you can also check out the Typst web app, which is currently in public beta.
To build Typst yourself, you need to have the latest stable Rust installed. Then, you can build the CLI with the following command:
cargo build -p typst-cli --release
The optimized binary will be stored in target/release/
.
We would love to see contributions from the community. If you experience bugs, feel free to open an issue or send a PR with a fix. For new features, we would invite you to open an issue first so we can explore the design space together. If you want to contribute and are wondering how everything works, also check out the ARCHITECTURE.md
file. It explains how the compiler works.
All of Typst has been designed with three key goals in mind: Power, simplicity, and performance. We think it's time for a system that matches the power of LaTeX, is easy to learn and use, all while being fast enough to realize instant preview. To achieve these goals, we follow three core design principles:
Simplicity through Consistency: If you know how to do one thing in Typst, you should be able to transfer that knowledge to other things. If there are multiple ways to do the same thing, one of them should be at a different level of abstraction than the other. E.g. it's okay that = Introduction
and #heading[Introduction]
do the same thing because the former is just syntax sugar for the latter.
Power through Composability: There are two ways to make something flexible: Have a knob for everything or have a few knobs that you can combine in many ways. Typst is designed with the second way in mind. We provide systems that you can compose in ways we've never even thought of. TeX is also in the second category, but it's a bit low-level and therefore people use LaTeX instead. But there, we don't really have that much composability. Instead, there's a package for everything (\usepackage{knob}
).
Performance through Incrementality: All Typst language features must accommodate for incremental compilation. Luckily we have comemo
, a system for incremental compilation which does most of the hard work in the background.
Author: typst
Source Code: https://github.com/typst/typst
License: Apache-2.0 license
1679451900
LSD-SLAM is a novel approach to real-time monocular SLAM. It is fully direct (i.e. does not use keypoints / features) and creates large-scale, semi-dense maps in real-time on a laptop. For more information see http://vision.in.tum.de/lsdslam where you can also find the corresponding publications and Youtube videos, as well as some example-input datasets, and the generated output as rosbag or .ply point cloud.
LSD-SLAM: Large-Scale Direct Monocular SLAM, J. Engel, T. Schöps, D. Cremers, ECCV '14
Semi-Dense Visual Odometry for a Monocular Camera, J. Engel, J. Sturm, D. Cremers, ICCV '13
1. Quickstart / Minimal Setup
First, install LSD-SLAM following 2.1 or 2.2, depending on your Ubuntu / ROS version. You don't need openFabMap for now.
Download the Room Example Sequence and extract it.
Launch the lsd_slam viewer:
rosrun lsd_slam_viewer viewer
Launch the lsd_slam main ros node:
rosrun lsd_slam_core live_slam image:=/image_raw camera_info:=/camera_info
Play the sequence:
rosbag play ~/LSD_room.bag
You should see one window showing the current keyframe with color-coded depth (from live_slam), and one window showing the 3D map (from viewer). If for some reason the initialization fails (i.e., after ~5s the depth map still looks wrong), focus the depth map and hit 'r' to re-initialize.
2. Installation
We tested LSD-SLAM on two different system configurations, using Ubuntu 12.04 (Precise) and ROS fuerte, or Ubuntu 14.04 (trusty) and ROS indigo. Note that building without ROS is not supported, however ROS is only used for input and output, facilitating easy portability to other platforms.
Install system dependencies:
sudo apt-get install ros-fuerte-libg2o liblapack-dev libblas-dev freeglut3-dev libqglviewer-qt4-dev libsuitesparse-dev libx11-dev
In your ROS package path, clone the repository:
git clone https://github.com/tum-vision/lsd_slam.git lsd_slam
Compile the two package by typing:
rosmake lsd_slam
We do not use catkin, however fortunately old-fashioned CMake-builds are still possible with ROS indigo. For this you need to create a rosbuild workspace (if you don't have one yet), using:
sudo apt-get install python-rosinstall
mkdir ~/rosbuild_ws
cd ~/rosbuild_ws
rosws init . /opt/ros/indigo
mkdir package_dir
rosws set ~/rosbuild_ws/package_dir -t .
echo "source ~/rosbuild_ws/setup.bash" >> ~/.bashrc
bash
cd package_dir
Install system dependencies:
sudo apt-get install ros-indigo-libg2o ros-indigo-cv-bridge liblapack-dev libblas-dev freeglut3-dev libqglviewer-dev libsuitesparse-dev libx11-dev
In your ROS package path, clone the repository:
git clone https://github.com/tum-vision/lsd_slam.git lsd_slam
Compile the two package by typing:
rosmake lsd_slam
If you want to use openFABMAP for large loop closure detection, uncomment the following lines in lsd_slam_core/CMakeLists.txt
:
#add_subdirectory(${PROJECT_SOURCE_DIR}/thirdparty/openFabMap)
#include_directories(${PROJECT_SOURCE_DIR}/thirdparty/openFabMap/include)
#add_definitions("-DHAVE_FABMAP")
#set(FABMAP_LIB openFABMAP )
Note for Ubuntu 14.04: The packaged OpenCV for Ubuntu 14.04 does not include the nonfree module, which is required for openFabMap (which requires SURF features). You need to get a full version of OpenCV with nonfree module, which is easiest by compiling your own version. We suggest to use the 2.4.8 version, to assure compatibility with the current indigo open-cv package.
3 Usage
LSD-SLAM is split into two ROS packages, lsd_slam_core
and lsd_slam_viewer
. lsd_slam_core
contains the full SLAM system, whereas lsd_slam_viewer
is optionally used for 3D visualization. Please also read General Notes for good results below.
lsd_slam_core
We provide two different usage modes, one meant for live-operation (live_slam
) using ROS input/output, and one dataset_slam
to use on datasets in the form of image files.
live_slam
If you want to directly use a camera.
rosrun lsd_slam_core live_slam /image:=<yourstreamtopic> /camera_info:=<yourcamera_infotopic>
When using ROS camera_info, only the image dimensions and the K
matrix from the camera info messages will be used - hence the video has to be rectified.
Alternatively, you can specify a calibration file using
rosrun lsd_slam_core live_slam /image:=<yourstreamtopic> _calib:=<calibration_file>
In this case, the camera_info topic is ignored, and images may also be radially distorted. See the Camera Calibration section for details on the calibration file format.
dataset_slam
rosrun lsd_slam_core dataset_slam _files:=<files> _hz:=<hz> _calib:=<calibration_file>
Here, <files>
can either be a folder containing image files (which will be sorted alphabetically), or a text file containing one image file per line. <hz>
is the framerate at which the images are processed, and <calibration_file>
the camera calibration file.
Specify _hz:=0
to enable sequential tracking and mapping, i.e. make sure that every frame is mapped properly. Note that while this typically will give best results, it can be much slower than real-time operation.
LSD-SLAM operates on a pinhole camera model, however we give the option to undistort images before they are being used. You can find some sample calib files in lsd_slam_core/calib
.
fx/width fy/height cx/width cy/height d
in_width in_height
"crop" / "full" / "none" / "e1 e2 e3 e4 0"
out_width out_height
Here, the values in the first line are the camera intrinsics and radial distortion parameter as given by the PTAM cameracalibrator, in_width and in_height is the input image size, and out_width out_height is the desired undistorted image size. The latter can be chosen freely, however 640x480 is recommended as explained in section 3.1.6. The third line specifies how the image is distorted, either by specifying a desired camera matrix in the same format as the first four intrinsic parameters, or by specifying "crop", which crops the image to maximal size while including only valid image pixels.
This one is without radial distortion correction, as a special case of ATAN camera model but without the computational cost:
fx/width fy/height cx/width cy/height 0
width height
none
width height
fx fy cx cy k1 k2 p1 p2
inputWidth inputHeight
"crop" / "full" / "none" / "e1 e2 e3 e4 0"
outputWidth outputHeight
r
: Do a full reset
d / e
: Cycle through debug displays (in particular color-coded variance and color-coded inverse depth).
o
: Toggle on screen info display
m
: Save current state of the map (depth & variance) as images to lsd_slam_core/save/
p
: Brute-Force-Try to find new constraints. May improve the map by finding more constraints, but will block mapping for a while.
l
: Manually indicate that tracking is lost: will stop tracking and mapping, and start the re-localizer.
A number of things can be changed dynamically, using (for ROS fuerte)
rosrun dynamic_reconfigure reconfigure_gui
or (for ROS indigo)
rosrun rqt_reconfigure rqt_reconfigure
Parameters are split into two parts, ones that enable / disable various sorts of debug output in /LSD_SLAM/Debug
, and ones that affect the actual algorithm, in /LSD_SLAM
. Note that debug output options from /LSD_SLAM/Debug
only work if lsd_slam_core is built with debug info, e.g. with set(ROS_BUILD_TYPE RelWithDebInfo)
.
minUseGrad
: [double] Minimal absolute image gradient for a pixel to be used at all. Increase if your camera has large image noise, decrease if you have low image-noise and want to also exploit small gradients.cameraPixelNoise
: [double] Image intensity noise used for e.g. tracking weight calculation. Should be set larger than the actual sensor-noise, to also account for noise originating from discretization / linear interpolation.KFUsageWeight
: [double] Determines how often keyframes are taken, depending on the overlap to the current keyframe. Larger -> more keyframes.KFDistWeight
: [double] Determines how often keyframes are taken, depending on the distance to the current Keyframe. Larger -> more keyframes.doSLAM
: [bool] Toggle global mapping component on/off. Only takes effect after a reset.doKFReActivation
: [bool] Toggle keyframe re-activation on/off: If close to an existing keyframe, re-activate it instead of creating a new one. If false, the map will continually grow even if the camera moves in a relatively constrained area; If false, the number of keyframes will not grow arbitrarily.doMapping
: [bool] Toggle entire keyframe creating / update module on/off: If false, only tracking stays active, which will prevent rapid motion or moving objects from corrupting the map.useFabMap
: [bool] Use openFABMAP to find large loop-closures. Only takes effect after a reset, and requires LSD-SLAM to be compiled with FabMap.allowNegativeIdepths
: [bool] Allow idepth to be (slightly) negative to avoid introducing a bias for far-away points.useSubpixelStereo
: [bool] Compute subpixel-accurate stereo disparity.useAffineLightningEstimation
: [bool] EXPERIMENTAL: Correct for global affine intensity changes during tracking. Might help if you have problems with auto-exposure.multiThreading
: [bool] Toggle multi-threading of depth map estimation. Disable for less CPU usage, but possibly slightly less quality.maxLoopClosureCandidates
: [int] Maximal number of loop-closures that are tracked initially for each new keyframe.loopclosureStrictness
: [double] Threshold on reciprocal loop-closure consistency check, to be added to the map. Larger -> more (possibly wrong) loop-closures.relocalizationTH
: [double] How good a relocalization-attempt has to be to be accepted. Larger -> more strict.depthSmoothingFactor
: [double] How much to smooth the depth map. Larger -> less smoothing.Useful for debug output are:
plotStereoImages
: [bool] Plot searched stereo lines, and color-coded stereo-results. Nice visualization of what's going on, however drastically decreases mapping speed.plotTracking
: [bool] Plot final tracking residual. Nice visualization of what's going on, however drastically decreases tracking speed.continuousPCOutput
: [bool] Publish current keyframe's point cloud after each update, to be seen in the viewer. Nice visualization, however bad for performance and bandwidth.minUseGrad
and cameraPixelNoise
to fit the sensor-noise and intensity contrast of your camera.KFUsageWeight
and KFDistWeight
slightly to generate more keyframes.The viewer is only for visualization. It can also be used to output a generated point cloud as .ply. For live operation, start it using
rosrun lsd_slam_viewer viewer
You can use rosbag to record and re-play the output generated by certain trajectories. Record & playback using
rosbag record /lsd_slam/graph /lsd_slam/keyframes /lsd_slam/liveframes -o file_pc.bag
rosbag play file_pc.bag
You should never have to restart the viewer node, it resets the graph automatically.
If you just want to lead a certain pointcloud from a .bag file into the viewer, you can directly do that using
rosrun lsd_slam_viewer viewer file_pc.bag
r
: Reset, will clear all displayed data.
w
: Print the number of points / currently displayed points / keyframes / constraints to the console.
p
: Write currently displayed points as point cloud to file lsd_slam_viewer/pc.ply, which can be opened e.g. in meshlab. Use in combination with sparsityFactor to reduce the number of points.
showKFCameras
: Toggle drawing of blue keyframe camera-frustrums. min: False, default: True, max: TrueshowKFPointclouds
: Toggle drawing of point clouds for all keyframes. min: False, default: True, max: TrueshowConstraints
: Toggle drawing of red/green pose-graph constraints. min: False, default: True, max: TrueshowCurrentCamera
: Toggle drawing of red frustrum for the current camera pose. min: False, default: True, max: TrueshowCurrentPointcloud
: Toggle drawing of the latest point cloud added to the map. min: False, default: True, max: TruepointTesselation
: Size of points. min: 0.0, default: 1.0, max: 5.0lineTesselation
: Width of lines. min: 0.0, default: 1.0, max: 5.0scaledDepthVarTH
: log10 of threshold on point's variance, in the respective keyframe's scale. min: -10.0, default: -3.0, max: 1.0absDepthVarTH
: log10 of threshold on point's variance, in absolute scale. min: -10.0, default: -1.0, max: 1.0minNearSupport
: Only plot points that have #minNearSupport similar neighbours (higher values remove outliers). min: 0, default: 7, max: 9cutFirstNKf
: Do not display the first #cutFirstNKf keyframe's point clouds, to remove artifacts left-over from the random initialization. min: 0, default: 5, max: 100sparsifyFactor
: Only plot one out of #sparsifyFactor points, selected at random. Use this to significantly speed up rendering for large maps. min: 1, default: 1, max: 100sceneRadius
: Defines near- and far clipping plane. Decrease to be able to zoom in more. min: 1, default: 80, max: 200saveAllVideo
: Save all rendered images... only use if you know what you are doing. min: False, default: False, max: TruekeepInMemory
: If set to false, the point cloud is only stored in OpenGL buffers, and not kept in RAM. This greatly reduces the required RAM for large maps, however also prohibits saving / dynamically changing sparsifyFactor and variance-thresholds. min: False, default: True, max: True4 Datasets
For convenience we provide a number of datasets, including the video, lsd-slam's output and the generated point cloud as .ply. See http://vision.in.tum.de/lsdslam
5 License
LSD-SLAM is licensed under the GNU General Public License Version 3 (GPLv3), see http://www.gnu.org/licenses/gpl.html.
For commercial purposes, we also offer a professional version under different licencing terms.
6 Troubleshoot / FAQ
How can I get the live-pointcloud in ROS to use with RVIZ?
You cannot, at least not on-line and in real-time. The reason is the following:
In the background, LSD-SLAM continuously optimizes the pose-graph, i.e., the poses of all keyframes. Each time a keyframe's pose changes (which happens all the time, if only by a little bit), all points from this keyframe change their 3D position with it. Hence, you would have to continuously re-publish and re-compute the whole pointcloud (at 100k points per keyframe and up to 1000 keyframes for the longer sequences, that's 100 million points, i.e., ~1.6GB), which would crush real-time performance.
Instead, this is solved in LSD-SLAM by publishing keyframes and their poses separately:
Points are then always kept in their keyframe's coodinate system: That way, a keyframe's pose can be changed without even touching the points. In fact, in the viewer, the points in the keyframe's coodinate frame are moved to a GLBuffer immediately and never touched again - the only thing that changes is the pushed modelViewMatrix before rendering.
Note that "pose" always refers to a Sim3 pose (7DoF, including scale) - which ROS doesn't even have a message type for.
If you need some other way in which the map is published (e.g. publish the whole pointcloud as ROS standard message as a service), the easiest is to implement your own Output3DWrapper.
Tracking immediately diverges / I keep getting "TRACKING LOST for frame 34 (0.00% good Points, which is -nan% of available points, DIVERGED)!"
Author: Tum-vision
Source Code: https://github.com/tum-vision/lsd_slam
License: GPL-3.0 license
1678972331
A software package for the modeling and simulation of nonsmooth dynamical systems in C++ and in Python.
Siconos is an open-source scientific software primarily targeted at modeling and simulating nonsmooth dynamical systems:
Other applications are found in Systems and Control (hybrid systems, differential inclusions, optimal control with state constraints), Optimization (Complementarity systems and Variational inequalities), Fluid Mechanics, Computer Graphics, ...
Read more about Siconos at the Siconos homepage
Assuming you have cloned the project into , to build and install the libraries and the python interface ::
mkdir build ;cd build
cmake -DUSER_OPTIONS_FILE=<your options file> <path-to-siconos-sources>
make -j 4 # or the number of cores available on your computer.
make test # optional
make install
More details in Siconos download and install guide.
docker run -ti gricad-registry.univ-grenoble-alpes.fr/nonsmooth/siconos-tutorials/siconos-master:latest
docker run -ti gricad-registry.univ-grenoble-alpes.fr/nonsmooth/siconos-tutorials/siconos-release-X.Y:latest
docker run -p 8888:8888 -ti gricad-registry.univ-grenoble-alpes.fr/nonsmooth/siconos-tutorials/siconoslab-master
docker run -p 8888:8888 -ti gricad-registry.univ-grenoble-alpes.fr/nonsmooth/siconos-tutorials/siconoslab-release-X.Y
Then, access in your browser at http://localhost:8888
Main components
Each component can be used either from a low-level language like C/C++ or from Python.
Collection of low-level algorithms for solving optimization problems arising in the simulation of nonsmooth dynamical systems:
Library for the modeling and simulation of nonsmooth dynamical systems.
Component for the simulation of mechanical systems in interaction with their environment:
Library to add a controller to a simulation. For now almost all the implemented control schemes are based on sliding modes with an implicit discretization.
This component can be used to
from siconos.kernel import LagrangianLinearTIDS, NewtonImpactNSL,\
LagrangianLinearTIR, Interaction, NonSmoothDynamicalSystem, MoreauJeanOSI,\
TimeDiscretisation, LCP, TimeStepping
from numpy import eye, empty
t0 = 0 # start time
T = 10 # end time
h = 0.005 # time step
r = 0.1 # ball radius
g = 9.81 # gravity
m = 1 # ball mass
e = 0.9 # restitution coeficient
theta = 0.5 # theta scheme
# the dynamical system
x = [1, 0, 0] # initial position
v = [0, 0, 0] # initial velocity
mass = eye(3) # mass matrix
mass[2, 2] = 2. / 5 * r * r
ball = LagrangianLinearTIDS(x, v, mass)
weight = [-m * g, 0, 0]
ball.setFExtPtr(weight) #set external forces
# Interaction ball-floor
H = [[1, 0, 0]]
nslaw = NewtonImpactNSL(e)
relation = LagrangianLinearTIR(H)
inter = Interaction(nslaw, relation)
# Model
bouncingBall = NonSmoothDynamicalSystem(t0, T)
# add the dynamical system to the non smooth dynamical system
bouncingBall.insertDynamicalSystem(ball)
# link the interaction and the dynamical system
bouncingBall.link(inter, ball)
# Simulation
# (1) OneStepIntegrators
OSI = MoreauJeanOSI(theta)
# (2) Time discretisation
t = TimeDiscretisation(t0, h)
# (3) one step non smooth problem
osnspb = LCP()
# (4) Simulation setup with (1) (2) (3)
s = TimeStepping(bouncingBall, t, OSI, osnspb)
# end of model definition
# computation
N = (T - t0) / h # the number of time steps
# time loop
while s.hasNextEvent():
s.computeOneStep()
s.nextStep()
Author: Siconos
Source Code: https://github.com/siconos/siconos
License: Apache-2.0 license
1678867398
Узнайте, как найти разницу в наборе между двумя наборами Python, используя метод разницы () и оператор разницы (-).
В Python наборы — это встроенные структуры данных, в которых хранится неупорядоченная коллекция неповторяющихся и неизменяемых элементов. Вы можете выполнять общие операции из теории множеств, такие как объединение, пересечение и разность множеств над множествами Python.
Этот туториал научит вас вычислять разницу между наборами в Python. Вы узнаете, как использовать встроенный метод set разность() и оператор - для поиска разности наборов, а также как отлаживать распространенные ошибки во время процесса.
Давайте начнем.
Что такое разница в наборе?
Прежде чем вычислять разность наборов для наборов Python, давайте быстро рассмотрим операцию разности наборов.
Имея два множества A и B, мы можем определить следующее:
Разность множества не является коммутативной операцией. Следовательно, А — В не то же самое, что А — В, если только множества А и В не равны, то есть А и В содержат одни и те же элементы.
Мы можем видеть это на простом примере ниже:
Изображение автора
В этом примере:
Следовательно, A – B – это {1,2,7}, множество элементов, присутствующих только в A. А B – A – это {21,10}, множество элементов, присутствующих только в B.
Установить разницу, используя метод разницы ()
Определим fruitsи to_eat, два набора Python, содержащие строки в качестве отдельных элементов.
Изображение автора
fruits = {"apples","oranges","berries","cherries"}
to_eat = {"apples","cereals","berries","bread"}
Теперь, чтобы найти фрукты — to_eat , давайте вызовем difference()метод на fruitsнаборе с to_eatаргументом:
print(fruits.difference(to_eat))
Output >> {'cherries', 'oranges'}
Точно так же, чтобы найти to_eat - fruit , давайте вызовем difference()метод на to_eatнаборе, как показано:
print(to_eat.difference(fruits))
Output >> {'cereals', 'bread'}
Установите разницу с помощью оператора разницы (-)
Мы также можем использовать оператор разности (-), чтобы найти разность множества.
Вернемся к тому же примеру: для множеств fruitsи to_eatиспользование оператора разности (-) выполняет эквивалентную операцию и возвращает те же результаты:
print(fruits - to_eat)
Output >> {'cherries', 'oranges'}
print(to_eat - fruits)
Output >> {'cereals', 'bread'}
Отладка распространенных ошибок различия наборов
В примерах, которые мы написали до сих пор, мы вычислили разницу между двумя наборами Python. Но не акцентировал внимание на том, что difference()метод работает иначе, чем разностный оператор.
Вы можете вызвать difference()метод для любого допустимого объекта набора. Однако вы можете передать один или несколько наборов или других итераций Python. Вот пример.
Определим set1, list1, list2, и list3:
set1 = {1,2,3,4,5}
list1 = [2,4,6]
list2 = [3,6,9]
list3 = [10,11]
Теперь мы можем вызвать difference()метод set1и передать list1, list2и list3в вызове метода.
print(set1.difference(list1,list2,list3))
Output >> {1, 5}
Метод разности в этом случае возвращает элементы {1,5} из набора, которые присутствуют только в , , и , а set1не в . list1list2list3
Однако, если вы попытаетесь сделать то же самое с оператором разности, вы столкнетесь с исключением TypeError. Поскольку - является бинарным оператором, который работает с двумя операндами, давайте объединим три списка, а затем попробуем вычислить разницу множества:
>>> set1 - (list1 + list2 + list3)
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for -: 'set' and 'list'
Как видно выше, в отличие от difference()метода, оператор - работает только с наборами Python. Таким образом, вам придется преобразовать другие итерации в наборы Python, прежде чем вычислять разницу, как показано ниже:
print(set1 - set(list1 + list2 + list3))
Output >> {1, 5}
Заключение
Давайте быстро рассмотрим, что мы узнали в этом уроке. Чтобы найти разницу в наборах, мы можем использовать либо difference()метод набора Python, либо оператор -. В то время как difference()вызов метода воздействует на набор и принимает одну или несколько итераций Python в качестве аргументов, оператор - позволяет выполнять операцию разности наборов только между двумя наборами Python . Если вы хотите изучить Python, ознакомьтесь со списком бесплатных ресурсов .
Оригинальный источник статьи: https://www.kdnuggets.com/
1678863600
了解如何使用 difference() 方法和差分 (-) 运算符查找两个 Python 集之间的集差。
在 Python 中,集合是内置数据结构,用于存储非重复和不可变元素的无序集合。您可以执行集合论中的常见操作,例如 Python 集合的并集、交集和集差。
本教程将教您如何在 Python 中计算集差。您将学习如何使用内置的集合方法 difference() 和 - 运算符来查找集合差异,以及如何调试过程中的常见错误。
让我们开始吧。
什么是集差?
在计算 Python 集合的集合差异之前,让我们快速回顾一下集合差异操作。
给定两个集合 A 和 B,我们可以定义以下内容:
集差不是交换运算。因此,A - B 与 A - B 不同,除非集合 A 和 B 相等,即 A 和 B 包含相同的元素。
我们可以从下面的简单示例中看出这一点:
图片作者
在这个例子中:
因此,A - B 是 {1,2,7},仅存在于 A 中的元素集。而 B - A 是 {21,10},仅存在于 B 中的元素集。
使用 difference() 方法设置差异
让我们定义fruits和to_eat,两个包含字符串作为单独元素的 Python 集合。
图片作者
fruits = {"apples","oranges","berries","cherries"}
to_eat = {"apples","cereals","berries","bread"}
现在要找到fruits - to_eat,让我们调用集合difference()上的方法作为参数:fruitsto_eat
print(fruits.difference(to_eat))
Output >> {'cherries', 'oranges'}
同样,要找到to_eat - fruits,让我们调用集合difference()上的方法to_eat,如下所示:
print(to_eat.difference(fruits))
Output >> {'cereals', 'bread'}
使用差分运算符 (-) 设置差分
我们还可以使用差异运算符(-) 来查找集合差异。
让我们重温同一个例子:对于集合fruitsand to_eat,使用差分运算符 (-) 执行等效运算并返回相同的结果:
print(fruits - to_eat)
Output >> {'cherries', 'oranges'}
print(to_eat - fruits)
Output >> {'cereals', 'bread'}
调试常见集差错误
在我们目前编写的示例中,我们计算了两个 Python 集之间的差异。但没有强调该difference()方法与差分运算符的工作方式有何不同。
您可以在任何有效的集合对象上调用该difference()方法。但是,您可以传入一组或多组或其他 Python 可迭代对象。这是一个例子。
让我们定义set1、list1、list2和list3:
set1 = {1,2,3,4,5}
list1 = [2,4,6]
list2 = [3,6,9]
list3 = [10,11]
现在我们可以调用difference()上的方法,并在方法调用中 set1传入list1、list2和。list3
print(set1.difference(list1,list2,list3))
Output >> {1, 5}
在这种情况下,difference 方法从集合中返回元素 {1,5},这些元素仅存在于 、set1和 中,而不存在于list1、list2和中list3。
但是,如果您尝试使用差异运算符做同样的事情,您将遇到异常TypeError。由于 - 是一个对两个操作数进行操作的二元运算符,让我们连接三个列表,然后尝试计算集合差异:
>>> set1 - (list1 + list2 + list3)
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for -: 'set' and 'list'
如上所示,与difference()方法不同,-运算符仅适用于 Python 集合。因此,在计算差异之前,您必须将其他可迭代对象转换为 Python 集合,如下所示:
print(set1 - set(list1 + list2 + list3))
Output >> {1, 5}
结论
让我们快速回顾一下我们在本教程中学到的内容。要找到集合差异,我们可以使用difference()Python 集合上的方法或 - 运算符。虽然difference()方法调用作用于一个集合并接受一个或多个 Python 可迭代对象作为参数,但 - 运算符允许您仅在两个 Python 集合之间执行集合差异操作。如果您想学习 Python,请查看此免费资源列表。
文章原文出处:https: //www.kdnuggets.com/
1678859700
Learn how to find the set difference between two Python sets using the difference() method and the difference (-) operator.
In Python, sets are built-in data structures that store an unordered collection of non-repeating and immutable elements. You can perform common operations from set theory such as union, intersection, and set difference on Python sets.
This tutorial will teach you how to compute set difference in Python. You will learn how to use the built-in set method difference() and - operator to find the set difference, and how to debug common errors during the process.
Let’s get started.
What Is Set Difference?
Before computing set difference on Python sets, let's quickly review the set difference operation.
Given two sets A and B, we can define the following:
Set difference is not a commutative operation. Therefore, A - B is not the same as A - B unless the sets A and B are equal, that is, A and B contain the same elements.
We can see this from the simple example below:
Image by Author
In this example:
Therefore, A - B is {1,2,7}, the set of elements present only in A. And B - A is {21,10}, the set of elements present only in B.
Set Difference Using the difference() Method
Let us define fruits
and to_eat
, two Python sets containing strings as the individual elements.
Image by Author
fruits = {"apples","oranges","berries","cherries"}
to_eat = {"apples","cereals","berries","bread"}
Now to find fruits - to_eat, let’s call the difference()
method on the fruits
set with to_eat
as the argument:
print(fruits.difference(to_eat))
Output >> {'cherries', 'oranges'}
Similarly, to find to_eat - fruits, let’s call the difference()
method on the to_eat
set, as shown:
print(to_eat.difference(fruits))
Output >> {'cereals', 'bread'}
Set Difference Using the Difference Operator (-)
We can also use the difference operator (-) to find the set difference.
Let’s revisit the same example: For the sets fruits
and to_eat
, using the difference operator (-) performs an equivalent operation and returns the same results:
print(fruits - to_eat)
Output >> {'cherries', 'oranges'}
print(to_eat - fruits)
Output >> {'cereals', 'bread'}
Debugging Common Set Difference Errors
In the examples we have coded so far, we computed the difference between two Python sets. But did not emphasize how the difference()
method works differently than the difference operator.
You can call the difference()
method on any valid set object. However, you can pass in one or more sets or other Python iterables. Here’s an example.
Let’s define set1
, list1
, list2
, and list3
:
set1 = {1,2,3,4,5}
list1 = [2,4,6]
list2 = [3,6,9]
list3 = [10,11]
Now we can call the difference()
method on the set1
and pass in list1
, list2
, and list3
in the method call.
print(set1.difference(list1,list2,list3))
Output >> {1, 5}
The difference method, in this case, returns the elements {1,5} from the set that are present only in set1
and not in list1
, list2
, and list3
.
However, if you try doing the same thing with the difference operator, you will run into a TypeError
exception. As - is a binary operator that operates on two operands, let’s concatenate the three lists, and then try computing the set difference:
>>> set1 - (list1 + list2 + list3)
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for -: 'set' and 'list'
As seen above, unlike the difference()
method, the - operator only works with Python sets. So you’ll have to cast other iterables into Python sets before computing the difference, as shown:
print(set1 - set(list1 + list2 + list3))
Output >> {1, 5}
Conclusion
Let us quickly review what we’ve learned in this tutorial. To find the set difference, we can use either the difference()
method on a Python set or the - operator. While the difference()
method call acts on a set and takes in one or more Python iterables as the arguments, the - operator lets you perform set difference operation between two Python sets only. If you’re looking to learn Python, check out this list of free resources.
Original article source at: https://www.kdnuggets.com/
1675708620
In this article you will learn how to create Alarm Clock using HTML CSS and JavaScript. Already I have shared tutorials on many types of digital clocks and analog clocks.
Now you know how to create JavaScript Alarm Clock. This project(How to make an alarm clock in HTML CSS and JavaScript?) is fully functional i.e. here you can set the alarm at your desired time. I have made this Digital Clock with Alarm in a very advanced way.
You can make this JavaScript Alarm Clock with Sound very easily if you know basic html css and javascript. Here you will find the necessary source code, live preview and explanation.
An alarm clock is a useful tool for setting reminders and ensuring that you wake up on time. With the advent of web development, it is now possible to create an alarm clock using JavaScript. This type of alarm clock can be accessed through a web browser, making it convenient to use on any device with internet access.
The basic functionality of a JavaScript alarm clock is to set a specific time for the alarm to go off and display a message or play a sound when that time is reached. This can be achieved using the JavaScript Date object and the setTimeout or setInterval functions.
As you can see above I have created a box in a web page for this Simple Alarm Clock in HTML. This box contains all the information of this Alarm Clock. This alarm clock has a small box at the front which shows the time. Then there are two input boxes in which you can add your alarm time.
Basically here you can add hours and minutes time. Then there is a button below that will generate an alarm for the time you input.
If you want to create this advanced JavaScript Alarm Clock then there is no reason to worry. Here I will tell you step by step and share the necessary source code how to create Alarm clock in Vanilla Javascript. If you just want the source code then use the download button below the article
I first created a basic structure using the HTML and CSS code below. This box has width: 90%, max-width: 27.25em and background color is white.
<div class="wrapper">
</div>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
background-color: #377dff;
}
.hide {
display: none;
}
.wrapper {
background-color: #ffffff;
width: 90%;
max-width: 27.25em;
padding: 3.12em 5em;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 0.5em;
}
Now I have created a place to see the time ie real time can be seen here. Here the basic area is created. Later I will arrange to show the time from your device by javascript. Also this time area is designed by some css and different colors are added.
<div class="timer-display">00:00:00</div>
.timer-display {
font-size: 2.18em;
text-align: center;
box-shadow: 0 0 20px rgba(0,139,253,0.25);
padding: 10px 30px;
font-family: "Roboto Mono", monospace;
}
Now we have to add various functions of Elam Clock ie input box, submit button and alarm list. We will add all these by following html css.
First here I have created two input boxes in which you can input the time in hours and minutes. Here I have used type=”number” of input box so only number can be input.
<div class="container">
</div>
<div class="inputs">
<input type="number" id="hourInput" placeholder="00" min="0" max="23" />
<input type="number" id="minuteInput" placeholder="00" min="0" max="59"/>
</div>
.inputs {
display: flex;
align-items: center;
justify-content: center;
gap: 1em;
margin-top: 2em;
}
.inputs input {
width: 2.8em;
font-size: 1.3em;
border: 1px solid #000000;
border-radius: 0.1em;
padding: 0.4em 0.2em;
}
Now we will create a button in this html Alarm clock. Which will basically work as a submit button. When you add your alarm time in that input box then clicking on this button will make that time effective for alarm.
<button id="set">Add Alarm</button>
#set {
background-color: #377dff;
border: none;
padding: 1em 2.2em;
display: block;
margin: 1.5em auto 0 auto;
border-radius: 0.2em;
color: #ffffff;
}
Now we will create an area in which the parameters you input are listed. Here only we have created basic area by html. Later we will activate everything with javascript.
<div class="activeAlarms"></div>
Now we will implement the various information of this JavaScript Alarm Clock with Sound by JavaScript. Here I have used a lot of javascript because I have made this design very advanced.
This code appears to be setting up a JavaScript program for an alarm clock. The first line selects an element with the class “timer-display” and assigns it to the variable “timerRef.” The next three lines select elements with the IDs “hourInput,” “minuteInput,” and “activeAlarms,” and assigns them to the respective variables.
The next line selects an element with the ID “set” and assigns it to the variable “setAlarm.” The “alarmsArray” variable is an empty array that will later be used to store alarms.
The “alarmSound” variable is a new instance of the HTML5 “Audio” object, which is set to play the file “./alarm.mp3.” You can use whatever audio you want in this alarm clock. Finally, the “initialHour,” “initialMinute,” and “alarmIndex” variables are all set to 0.
let timerRef = document.querySelector(".timer-display");
const hourInput = document.getElementById("hourInput");
const minuteInput = document.getElementById("minuteInput");
const activeAlarms = document.querySelector(".activeAlarms");
const setAlarm = document.getElementById("set");
let alarmsArray = [];
let alarmSound = new Audio("./alarm.mp3");
let initialHour = 0,
initialMinute = 0,
alarmIndex = 0;
This is a JavaScript function that takes a single argument, “value”, and returns a string. If the value is less than 10, it adds a leading “0” to the value, otherwise it returns the value as is. This function can be used to ensure that a single-digit number is represented as a two-digit number (e.g. “07” instead of “7”).
//Append zeroes for single digit
const appendZero = (value) => (value < 10 ? "0" + value : value);
This is a JavaScript function that takes two arguments: “parameter” and “value”. The function looks for an object inside the alarmsArray array, where the value of the key equal to the “parameter” passed to the function is equal to the “value” passed to the function.
If it finds a match, the function sets exists to true, assigns the matching object to the variable alarmObject and assigns the index of that object in the alarmsArray array to objIndex.
//Search for value in object
const searchObject = (parameter, value) => {
let alarmObject,
objIndex,
exists = false;
alarmsArray.forEach((alarm, index) => {
if (alarm[parameter] == value) {
exists = true;
alarmObject = alarm;
objIndex = index;
return false;
}
});
return [exists, alarmObject, objIndex];
};
This is a JavaScript function that displays the current time in a specific format and also check if any alarm is active and its time matches with the current time, if it matches it plays an alarm sound. As I said earlier the time can be seen in this advanced alarm clock in javascript.
It creates a new Date object, which is used to get the current hours, minutes, and seconds. The function uses the appendZero function to ensure that single-digit values are represented as two-digit values.
It then displays the current time in the format hours:minutes:seconds by updating the innerHTML of an element referred by timerRef.
Then it checks if any alarm is active by iterating over the alarmsArray, it compares alarm hour and alarm minute with the current hour and current minute, if it matches it plays an alarm sound using alarmSound.play() function. The alarmSound is looped continuously using alarmSound.loop = true.
//Display Time
function displayTimer() {
let date = new Date();
let [hours, minutes, seconds] = [
appendZero(date.getHours()),
appendZero(date.getMinutes()),
appendZero(date.getSeconds()),
];
//Display time
timerRef.innerHTML = `${hours}:${minutes}:${seconds}`;
//Alarm
alarmsArray.forEach((alarm, index) => {
if (alarm.isActive) {
if (`${alarm.alarmHour}:${alarm.alarmMinute}` === `${hours}:${minutes}`) {
alarmSound.play();
alarmSound.loop = true;
}
}
});
}
This is a JavaScript code that adds an event listener to two input elements, hourInput and minuteInput, to check the input value when it changes.
The inputCheck function takes a single argument, inputValue, which is the value of the input element. It converts the input value to an integer using parseInt(), and checks if the input value is less than 10, if so, it calls the appendZero function to add a leading “0” to the input value.
The function then returns the input value, which is then used to update the value of the input element.
The event listener is added to both hourInput and minuteInput, so when the value of either input changes, the inputCheck function is called and the value of the input element is updated. This ensures that any input that is less than 10 is represented as a two-digit number (e.g. “07” instead of “7”).
const inputCheck = (inputValue) => {
inputValue = parseInt(inputValue);
if (inputValue < 10) {
inputValue = appendZero(inputValue);
}
return inputValue;
};
hourInput.addEventListener("input", () => {
hourInput.value = inputCheck(hourInput.value);
});
minuteInput.addEventListener("input", () => {
minuteInput.value = inputCheck(minuteInput.value);
});
This is a JavaScript function that creates an HTML element for this simple javascript alarm clock, given an alarm object. It takes a single argument, alarmObj, which is an object containing information about the alarm.
The function starts by destructuring the properties of the alarm object, such as id, alarmHour, and alarmMinute, which are used to create the alarm element. It creates a div element with the class “alarm” and a data-id attribute equal to the id of the alarm. It sets the innerHTML of the div to show the alarm time in the format of alarmHour:alarmMinute.
Then it creates an input element which is a checkbox, the checkbox attribute type is set to ‘checkbox’. An event listener is added to the checkbox element so that whenever it’s clicked it calls the startAlarm() or stopAlarm() function depending on the checkbox state.
Then it creates a delete button element with a trash icon, an event listener is added to the delete button so that when it’s clicked it calls the deleteAlarm() function.
Finally, the function appends the checkbox, delete button, and the alarmDiv to the activeAlarms element.
//Create alarm div
const createAlarm = (alarmObj) => {
//Keys from object
const { id, alarmHour, alarmMinute } = alarmObj;
//Alarm div
let alarmDiv = document.createElement("div");
alarmDiv.classList.add("alarm");
alarmDiv.setAttribute("data-id", id);
alarmDiv.innerHTML = `<span>${alarmHour}: ${alarmMinute}</span>`;
//checkbox
let checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.addEventListener("click", (e) => {
if (e.target.checked) {
startAlarm(e);
} else {
stopAlarm(e);
}
});
alarmDiv.appendChild(checkbox);
//Delete button
let deleteButton = document.createElement("button");
deleteButton.innerHTML = `<i class="fa-solid fa-trash-can"></i>`;
deleteButton.classList.add("deleteButton");
deleteButton.addEventListener("click", (e) => deleteAlarm(e));
alarmDiv.appendChild(deleteButton);
activeAlarms.appendChild(alarmDiv);
};
This is a JavaScript code that adds an event listener to a button element, setAlarm, so that when the button is clicked, an alarm is created and added to the alarmsArray.
The event listener is added to the setAlarm button, so when it’s clicked the following actions are taken:
The alarmIndex variable is incremented by 1
It creates an alarm object, alarmObj, which contains the following properties:
It pushes the alarm object to the alarmsArray
It calls the createAlarm function, passing the alarm object as an argument, to create an HTML element for the alarm.
It resets the hourInput and minuteInput to their initial values by calling the appendZero function, and initialHour and initialMinute should be defined before calling the function.
//Set Alarm
setAlarm.addEventListener("click", () => {
alarmIndex += 1;
//alarmObject
let alarmObj = {};
alarmObj.id = `${alarmIndex}_${hourInput.value}_${minuteInput.value}`;
alarmObj.alarmHour = hourInput.value;
alarmObj.alarmMinute = minuteInput.value;
alarmObj.isActive = false;
console.log(alarmObj);
alarmsArray.push(alarmObj);
createAlarm(alarmObj);
hourInput.value = appendZero(initialHour);
minuteInput.value = appendZero(initialMinute);
});
This is a JavaScript function that initializes this Element(Build A Simple Alarm Clock in HTML CSS & JavaScript). It takes a single argument, e, which is an event object that gets passed when the function is called.
The function starts by getting the value of the data-id attribute of the parent element of the event target, which should be the alarm div element. It then calls the searchObject() function passing in the parameter “id” and the value of the data-id attribute as arguments. This function will search the alarmsArray for an alarm object that has a matching id and returns an array containing a boolean value indicating whether the alarm object was found, the alarm object, and the index of the alarm object in the alarmsArray.
//Start Alarm
const startAlarm = (e) => {
let searchId = e.target.parentElement.getAttribute("data-id");
let [exists, obj, index] = searchObject("id", searchId);
if (exists) {
alarmsArray[index].isActive = true;
}
};
This is a javascript function to stop this javascript alarm clock. It takes a single argument, e, which is an event object that gets passed when the function is called.
The function starts by getting the value of the data-id attribute of the parent element of the event target, which should be the alarm div element. It then calls the searchObject() function passing in the parameter “id” and the value of the data-id attribute as arguments. This function will search the alarmsArray for an alarm object that has a matching id and returns an array containing a boolean value indicating whether the alarm object was found, the alarm object, and the index of the alarm object in the alarmsArray.
If the alarm object is found, it will update the isActive property of the alarm object to false, which means the alarm is now inactive. And it will pause the alarmSound by calling the pause() method on the alarmSound object.
//Stop alarm
const stopAlarm = (e) => {
let searchId = e.target.parentElement.getAttribute("data-id");
let [exists, obj, index] = searchObject("id", searchId);
if (exists) {
alarmsArray[index].isActive = false;
alarmSound.pause();
}
};
This code defines a function called “deleteAlarm” that takes in an event object as an argument. This project(Simple Vanilla Javascript Alarm Clock) will activate the delete button inside the alarmList. The function uses the event object to target the parent element of the element that triggered the event and gets the “data-id” attribute of that element.
It then uses the searchObject function to find the object in the alarmsArray that has a matching “id” property. If the object is found, the function removes the element from the DOM and splices the object from the alarmsArray.
//delete alarm
const deleteAlarm = (e) => {
let searchId = e.target.parentElement.parentElement.getAttribute("data-id");
let [exists, obj, index] = searchObject("id", searchId);
if (exists) {
e.target.parentElement.parentElement.remove();
alarmsArray.splice(index, 1);
}
};
This code sets an interval to call the “displayTimer” function every time the window loads. That is, every time the page is loaded, the JavaScript Alarm Clock with Sound information will be deleted. It also initializes several variables: “initialHour” and “initialMinute” to 0, “alarmIndex” to 0, and “alarmsArray” to an empty array. The values of the “hourInput” and “minuteInput” elements are set to “appendZero(initialHour)” and “appendZero(initialMinute)” respectively.
The function appendZero
is not defined in this piece of code, it may be defined in another parts of the codebase or it may be a custom function that ensures that the input value has a leading zero if the input value is less than 10.
window.onload = () => {
setInterval(displayTimer);
initialHour = 0;
initialMinute = 0;
alarmIndex = 0;
alarmsArray = [];
hourInput.value = appendZero(initialHour);
minuteInput.value = appendZero(initialMinute);
};
We have created this alarm clock using JavaScript above. Now we will design this multiple alarm clock in js by some amount of css.
.alarm input[type="checkbox"] {
appearance: none;
height: 2em;
width: 3.75em;
background-color: #e2e2ec;
border-radius: 1em;
position: relative;
cursor: pointer;
outline: none;
}
.alarm input[type="checkbox"]:before {
position: absolute;
content: "";
background-color: #757683;
height: 1.43em;
width: 1.43em;
border-radius: 50%;
top: 0.25em;
left: 0.25em;
}
.alarm input[type="checkbox"]:checked {
background-color: #d2e2ff;
}
.alarm input[type="checkbox"]:checked:before {
background-color: #377dff;
left: 2em;
}
.deleteButton {
background-color: transparent;
font-size: 1.5em;
color: #377dff;
border: none;
cursor: pointer;
}
Hopefully from this article you have learned how to Build A Simple Alarm Clock in HTML CSS & JavaScript. Next time I will make it more advanced. As a result, even after you reload the page, all this information will be stored in your local storage. Be sure to comment how you liked this tutorial.
Original article source at: https://foolishdeveloper.com/
1673971440
Algorithm is a library of tools that is used to create intelligent applications.
Embedded frameworks require a minimum deployment target of iOS 8.
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapods
To integrate Algorithm's core features into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'Algorithm', '~> 3.1.0'
Then, run the following command:
$ pod install
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate Algorithm into your Xcode project using Carthage, specify it in your Cartfile:
github "CosmicMind/Algorithm"
Run carthage update
to build the framework and drag the built Algorithm.framework
into your Xcode project.
Algorithm is a growing project and will encounter changes throughout its development. It is recommended that the Changelog be reviewed prior to updating versions.
Samples
The following are samples to see how Algorithm may be used within your applications.
Each data structure within Algorithm is equipped with probability tools.
For example, determining the probability of rolling a 3 using a die of 6 numbers.
let die = [Int](arrayLiteral: 1, 2, 3, 4, 5, 6)
if 0.1 < die.probability(of: 3)
// Do something ...
}
For conditional probabilities that require a more complex calculation, use block statements.
let die = [Int](arrayLiteral: 1, 2, 3, 4, 5, 6)
let pOfX = die.probability { (number) in
return 5 < number || 0 == number % 3
}
if 0.33 < pOfX {
// Do something ...
}
The expected value of rolling a 3 or 6 with 100 trials using a die of 6 numbers.
let die = [Int](arrayLiteral: 1, 2, 3, 4, 5, 6)
if 20 < die.expectedValue(trials: 100, for: 3, 6) {
// Do something ...
}
The DoublyLinkedList data structure is excellent for large growing collections of data. Below is an example of its usage.
var listA = DoublyLinkedList<Int>()
listA.insert(atFront: 3)
listA.insert(atFront: 2)
listA.insert(atFront: 1)
var listB = DoublyLinkedList<Int>()
listB.insert(atBack: 4)
listB.insert(atBack: 5)
listB.insert(atBack: 6)
var listC = listA + listB
listC.cursorToFront()
var value = listC.cursor
while nil != value {
// Do something ...
value = listC.next()
}
The Stack data structure is a container of objects that are inserted and removed according to the last-in-first-out (LIFO) principle. Below is an example of its usage.
var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
while !stack.isEmpty {
let value = stack.pop()
// Do something ...
}
The Queue data structure is a container of objects that are inserted and removed according to the first-in-first-out (FIFO) principle. Below is an example of its usage.
var queue = Queue<Int>()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
while !queue.isEmpty {
let value = queue.dequeue()
// Do something ...
}
The Deque data structure is a container of objects that are inserted and removed according to the first-in-first-out (FIFO) and last-in-first-out (LIFO) principle. Essentially, a Deque is a Stack and Queue combined. Below are examples of its usage.
var dequeA = Deque<Int>()
dequeA.insert(atBack: 1)
dequeA.insert(atBack: 2)
dequeA.insert(atBack: 3)
while !dequeA.isEmpty {
let value = dequeA.removeAtFront()
// Do something ...
}
var dequeB = Deque<Int>()
dequeB.insert(atBack: 4)
dequeB.insert(atBack: 5)
dequeB.insert(atBack: 6)
while !dequeB.isEmpty {
let value = dequeB.removeAtFront()
// Do something ...
}
A RedBlackTree is a Balanced Binary Search Tree that maintains insert, remove, update, and search operations in a complexity of O(logn). The following implementation of a RedBlackTree also includes an order-statistic, which allows the data structure to be accessed using subscripts like an array or dictionary. RedBlackTrees may store unique keys or non-unique key values. Below is an example of its usage.
var ages = RedBlackTree<String, Int>(uniqueKeys: true)
ages.insert(value: 16, for: "Sarah")
ages.insert(value: 12, for: "Peter")
ages.insert(value: 23, for: "Alex")
let node = ages[1]
if "Peter" == node.key {
// Do something ...
}
SortedSets are a powerful data structure for algorithm and analysis design. Elements within a SortedSet are unique and insert, remove, and search operations have a complexity of O(logn). The following implementation of a SortedSet also includes an order-statistic, which allows the data structure to be accessed using an index subscript like an array. Below are examples of its usage.
let setA = SortedSet<Int>(elements: 1, 2, 3)
let setB = SortedSet<Int>(elements: 4, 3, 6)
let setC = SortedSet<Int>(elements: 7, 1, 2)
let setD = SortedSet<Int>(elements: 1, 7)
let setE = SortedSet<Int>(elements: 1, 6, 7)
// Union.
setA + setB
setA.union(setB)
// Intersection.
setC.intersection(setD)
// Subset.
setD < setC
setD.isSubset(of: setC)
// Superset.
setD > setC
setD.isSuperset(of: setC)
// Contains.
setE.contains(setA.first!)
// Probability.
setE.probability(of: setA.first!, setA.last!)
A SortedMultiSet is identical to a SortedSet, except that a SortedMultiSet allows non-unique elements. Look at SortedSet for examples of its usage.
A SortedDictionary is a powerful data structure that maintains a sorted set of keys with value pairs. Keys within a SortedDictionary are unique and insert, remove, update, and search operations have a complexity of O(logn).
A SortedMultiDictionary is identical to a SortedDictionary, except that a SortedMultiDictionary allows non-unique keys. Below is an example of its usage.
struct Student {
var name: String
}
let sarah = Student(name: "Sarah")
let peter = Student(name: "Peter")
let alex = Student(name: "Alex")
var students = SortedMultiDictionary<String, Student>()
students.insert(value: sarah, for: sarah.name)
students.insert(value: peter, for: peter.name)
students.insert(value: alex, for: alex.name)
for student in students {
// Do something ...
}
Author: CosmicMind
Source Code: https://github.com/CosmicMind/Algorithm
License: MIT license
1673301780
A multiset (bag) implementation in Crystal.
Add this to your application's shard.yml
:
dependencies:
multiset:
github: tcrouch/multiset.cr
require "multiset"
ms1 = Multiset{1, 1}
ms1 << 2 # => Multiset{1, 1, 2}
ms1.merge [3, 4] # => Multiset{1, 1, 2, 3, 4}
ms2 = Multiset.new [2, 3, 4]
ms2.subset_of?(ms1) # => true
ms1 & ms2 # => Multiset{2, 3, 4}
crystal spec
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Author: tcrouch
Source Code: https://github.com/tcrouch/multiset.cr
License: MIT license
1672833558
Bash has many environment variables for various purposes. The set command of Bash is used to modify or display the different attributes and parameters of the shell environment. This command has many options to perform the different types of tasks. The uses of set command for various purposes are described in this tutorial.
set [options] [arguments]
This command can be used with different types of options and arguments for different purposes. If no option or argument is used with this command, the shell variables are printed. The minus sign (-) is used with the command’s option to enable that option and the plus sign (+) is used with the command’s option to disable that option.
Three exit values can be returned by this command which are mentioned in the following:
The purposes of the most commonly used options of the set command are described in this part of the tutorial.
Option | Purpose |
---|---|
-a | It defines those variables or functions which are created or modified or exported. |
-b | It informs the job termination. |
-B | To do the task of the brace expansion. |
-C | It disables the overwriting feature of the existing file. |
-e | It exits for non-zero exit status value. |
-f | It disables the filename generation task. |
-h | It saves the location of the command where it has been used. |
-m | It enables job control. |
-n | It reads the commands. |
-t | It exits from the command after executing a single command. |
-u | It traces the unset variables. |
-v | It prints the shell input lines. |
-x | It displays the commands and their attributes sequentially. It is mainly used to debug the script. |
The uses of set command with different options are shown in this part of this tutorial.
Example 1: Using the Set Command with -a Option
Create a Bash file with the following script that enables the “set –a” command and initialize three variables named $v1, $v2, and $v3. These variables can be accessed after executing the script.
#!/bin/bash
#Enable -a option to read the values of the variables
set -a
#Initialize three variables
v1=78
v2=50
v3=35
Run the script using the following command:
$ bash set1.bash
Read the values of the variable using the “echo” command:
$ echo $v1 $v2 $v3
The following output appears after executing the previous commands:
Example 2: Using the Set Command with -C Option
Run the “cat” command to create a text file named testfile.txt. Next, run the “set –C” command to disable the overwriting feature. Next, run the “cat” command again to overwrite the file to check whether the overwriting feature is disabled or not.
$ cat > testfile.txt
$ set -C
$ cat > testfile.txt
The following output appears after executing the previous commands:
Example 3: Using the Set Command with -x Option
Create a Bash file with the following script that declares a numeric array of 6 elements. The values of the array are printed using for loop.
#!/bin/bash
#Declare an array
arr=(67 3 90 56 2 80)
#iterate the array values
for value in ${arr[@]}
do
echo $value
done
Execute the previous script by the following command:
$ bash set3.bash
Enable the debugging option using the following command:
$ set -x
The following output appears after executing the provided commands:
Example 4: Using the Set Command with -e Option
Create a Bash file with the following script that reads a file using the “cat” command before and after using the “set –e” command.
#!/bin/bash
#Read a non-existing file without setting set -e
cat myfile.txt
echo "Reading a file..."
#Set the set command with -e option
set -e
#Read a non-existing file after setting set -e
cat myfile.txt
echo "Reading a file..."
The following output appears after executing the provided commands. The first error message is shown because the file does not exist in the current location. The next message is then printed. But after executing the “set –e” command, the execution stops after displaying the error message.
Example 5: Using the Set Command with -u Option
Create a Bash file with the following script that initializes a variable but prints the initialized and uninitialized variable before and after using the “set –u” command.
#!/bin/bash
#Assign value to a variable
strvar="Bash Programming"
printf "$strvar $intvar\n"
#Set the set command with -u option
set -u
#Assign value to a variable
strvar="Bash Programming"
printf "\n$strvar $intvar\n"
The following output appears after executing the previous script. Here, the error is printed for the uninitialized variable:
Example 6: Using the Set Command with -f Option
Run the following command to print the list of all text files of the current location:
$ ls *.txt
Run the following command to disable the globbing:
$ set –f
Run the following command again to print the list of all text files of the current location:
$ ls *.txt
The following output appears after executing the previous script. Based on the output, the “ls *.txt” command did not work after setting “set –f” command:
Example 7: Split the String Using the Set Command with Variable
Create a Bash file with the following script that splits the string value based on the space using the “set – variable” command. The split values are printed later.
#!/bin/bash
#Define a string variable
myvar="Learn bash programming"
#Set the set command without option and with variable
set -- $myvar
#Print the split value
printf "$1\n$2\n$3\n"
The following output appears after executing the previous script. The string value is divided into three parts based on the space that is printed:
The uses of the different options of the “set” command are shown in this tutorial using multiple examples to know the basic uses of this command.
Original article source at: https://linuxhint.com/
1671617416
When generating a PDF with Dompdf then it ignores fonts that are not available in its internally – Helvetica, Times-Roman, Courier, Zapf-Dingbats, Symbol.
Require to load the fonts for use in PDF creation which is not existing in Dompdf internal fonts.
In this tutorial, I am creating a PDF of MySQL database table records and set its font-family using Dompdf.
Create users
table and add some records.
CREATE TABLE `users` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Create a config.php
for the database connection.
Completed Code
<?php
$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "tutorial"; /* Database name */
$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
fonts
folder at the project root.fonts
folder. I have copied OpenSans-Regular.ttf
and OpenSans-Bold.ttf
to the folder.Create a new pdf.php
file.
Load Fonts and Use it
Create $html
variable to store data in HTML format for pdf generation.
Load fonts using @font-face
CSS rule.
In the example, I am loading OpenSans-Regular
and OpenSans-Bold
fonts.
Pass the file path in src
.
Now, use these fonts in the selectors.
I used 'OpenSans-Bold'
in <table >
header columns and 'OpenSans-Regular'
in <table >
body columns.
Add data and create a PDF
Fetch all records from the users
table and create new rows.
Create an object of Dompdf
and pass $html
in loadHtml()
method.
Completed Code
<?php
include "config.php";
$html = "<style>
@font-face {
font-family: 'OpenSans-Regular';
font-style: normal;
font-weight: normal;
src: url(http://" . $_SERVER['SERVER_NAME']."/dompdf/fonts/OpenSans-Regular.ttf) format('truetype');
}
@font-face {
font-family: 'OpenSans-Bold';
font-style: normal;
font-weight: 700;
src: url(http://" . $_SERVER['SERVER_NAME']."/dompdf/fonts/OpenSans-Bold.ttf) format('truetype');
}
table thead tr td{
font-family: 'OpenSans-Bold';
}
table tbody tr td{
font-family: 'OpenSans-Regular';
}
</style>";
$html .= "<table border='1' width='100%' style='border-collapse: collapse;'>
<thead>
<tr>
<td>S.no</td>
<td>Username</td>
<td>Name</td>
<td>Email</td>
</tr>
</thead>
<tbody>
";
$usersData = mysqli_query($con,"select * from users");
$sno = 1;
while($row = mysqli_fetch_assoc($usersData)){
$html .= "<tr>
<td>".$sno++."</td>
<td>".$row['username']."</td>
<td>".$row['name']."</td>
<td>".$row['email']."</td>
</tr>";
}
$html .= "</tbody></table>";
$filename = "newpdffile";
// include autoloader
require_once 'dompdf/autoload.inc.php';
// reference the Dompdf namespace
use Dompdf\Dompdf;
// instantiate and use the dompdf class
$dompdf = new Dompdf();
$dompdf->loadHtml($html);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');
// Render the HTML as PDF
$dompdf->render();
// Output the generated PDF to Browser
$dompdf->stream($filename);
Use @font-face
CSS rule to load your font-family and use it in your required selector.
If you found this tutorial helpful then don't forget to share.
Original article source at: https://makitweb.com/
1669099573
In this article, we will know what is face recognition and how is different from face detection. We will go briefly over the theory of face recognition and then jump on to the coding section. At the end of this article, you will be able to make a face recognition program for recognizing faces in images as well as on a live webcam feed.
In computer vision, one essential problem we are trying to figure out is to automatically detect objects in an image without human intervention. Face detection can be thought of as such a problem where we detect human faces in an image. There may be slight differences in the faces of humans but overall, it is safe to say that there are certain features that are associated with all the human faces. There are various face detection algorithms but Viola-Jones Algorithm is one of the oldest methods that is also used today and we will use the same later in the article. You can go through the Viola-Jones Algorithm after completing this article as I’ll link it at the end of this article.
Face detection is usually the first step towards many face-related technologies, such as face recognition or verification. However, face detection can have very useful applications. The most successful application of face detection would probably be photo taking. When you take a photo of your friends, the face detection algorithm built into your digital camera detects where the faces are and adjusts the focus accordingly.
For a tutorial on Real-Time Face detection
Now that we are successful in making such algorithms that can detect faces, can we also recognise whose faces are they?
Face recognition is a method of identifying or verifying the identity of an individual using their face. There are various algorithms that can do face recognition but their accuracy might vary. Here I am going to describe how we do face recognition using deep learning.
So now let us understand how we recognise faces using deep learning. We make use of face embedding in which each face is converted into a vector and this technique is called deep metric learning. Let me further divide this process into three simple steps for easy understanding:
Face Detection: The very first task we perform is detecting faces in the image or video stream. Now that we know the exact location/coordinates of face, we extract this face for further processing ahead.
Feature Extraction: Now that we have cropped the face out of the image, we extract features from it. Here we are going to use face embeddings to extract the features out of the face. A neural network takes an image of the person’s face as input and outputs a vector which represents the most important features of a face. In machine learning, this vector is called embedding and thus we call this vector as face embedding. Now how does this help in recognizing faces of different persons?
While training the neural network, the network learns to output similar vectors for faces that look similar. For example, if I have multiple images of faces within different timespan, of course, some of the features of my face might change but not up to much extent. So in this case the vectors associated with the faces are similar or in short, they are very close in the vector space. Take a look at the below diagram for a rough idea:
Now after training the network, the network learns to output vectors that are closer to each other(similar) for faces of the same person(looking similar). The above vectors now transform into:
We are not going to train such a network here as it takes a significant amount of data and computation power to train such networks. We will use a pre-trained network trained by Davis King on a dataset of ~3 million images. The network outputs a vector of 128 numbers which represent the most important features of a face.
Now that we know how this network works, let us see how we use this network on our own data. We pass all the images in our data to this pre-trained network to get the respective embeddings and save these embeddings in a file for the next step.
Comparing faces: Now that we have face embeddings for every face in our data saved in a file, the next step is to recognise a new t image that is not in our data. So the first step is to compute the face embedding for the image using the same network we used above and then compare this embedding with the rest of the embeddings we have. We recognise the face if the generated embedding is closer or similar to any other embedding as shown below:
So we passed two images, one of the images is of Vladimir Putin and other of George W. Bush. In our example above, we did not save the embeddings for Putin but we saved the embeddings of Bush. Thus when we compared the two new embeddings with the existing ones, the vector for Bush is closer to the other face embeddings of Bush whereas the face embeddings of Putin are not closer to any other embedding and thus the program cannot recognise him.
In the field of Artificial Intelligence, Computer Vision is one of the most interesting and Challenging tasks. Computer Vision acts like a bridge between Computer Software and visualizations around us. It allows computer software to understand and learn about the visualizations in the surroundings. For Example: Based on the color, shape and size determining the fruit. This task can be very easy for the human brain however in the Computer Vision pipeline, first we gather the data, then we perform the data processing activities and then we train and teach the model to understand how to distinguish between the fruits based on size, shape and color of fruit.
Currently, various packages are present to perform machine learning, deep learning and computer vision tasks. By far, computer vision is the best module for such complex activities. OpenCV is an open-source library. It is supported by various programming languages such as R, Python. It runs on most of the platforms such as Windows, Linux and MacOS.
To know more about how face recognition works on opencv, check out the free course on face recognition in opencv.
Advantages of OpenCV:
Installation:
Here we will be focusing on installing OpenCV for python only. We can install OpenCV using pip or conda(for anaconda environment).
Using pip, the installation process of openCV can be done by using the following command in the command prompt.
pip install opencv-python
If you are using anaconda environment, either you can execute the above code in anaconda prompt or you can execute the following code in anaconda prompt.
conda install -c conda-forge opencv
In this section, we shall implement face recognition using OpenCV and Python. First, let us see the libraries we will need and how to install them:
OpenCV is an image and video processing library and is used for image and video analysis, like facial detection, license plate reading, photo editing, advanced robotic vision, optical character recognition, and a whole lot more.
The dlib library, maintained by Davis King, contains our implementation of “deep metric learning” which is used to construct our face embeddings used for the actual recognition process.
The face_recognition library, created by Adam Geitgey, wraps around dlib’s facial recognition functionality, and this library is super easy to work with and we will be using this in our code. Remember to install dlib library first before you install face_recognition.
To install OpenCV, type in command prompt
pip install opencv-python |
I have tried various ways to install dlib on Windows but the easiest of all of them is via Anaconda. First, install Anaconda (here is a guide to install it) and then use this command in your command prompt:
conda install -c conda-forge dlib |
Next to install face_recognition, type in command prompt
pip install face_recognition |
Now that we have all the dependencies installed, let us start coding. We will have to create three files, one will take our dataset and extract face embedding for each face using dlib. Next, we will save these embedding in a file.
In the next file we will compare the faces with the existing the recognise faces in images and next we will do the same but recognise faces in live webcam feed
First, you need to get a dataset or even create one of you own. Just make sure to arrange all images in folders with each folder containing images of just one person.
Next, save the dataset in a folder the same as you are going to make the file. Now here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Now that we have stored the embedding in a file named “face_enc”, we can use them to recognise faces in images or live video stream.
Here is the script to recognise faces on a live webcam feed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
|
https://www.youtube.com/watch?v=fLnGdkZxRkg
Although in the example above we have used haar cascade to detect faces, you can also use face_recognition.face_locations to detect a face as we did in the previous script
The script for detecting and recognising faces in images is almost similar to what you saw above. Try it yourself and if you can’t take a look at the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
|
Output:
InputOutput
This brings us to the end of this article where we learned about face recognition.
You can also upskill with Great Learning’s PGP Artificial Intelligence and Machine Learning Course. The course offers mentorship from industry leaders, and you will also have the opportunity to work on real-time industry-relevant projects.
Original article source at: https://www.mygreatlearning.com