हैंडराइटिंग की पहचान करने वाले एपीआई की मदद से, हाथ से लिखे गए इनपुट से टेक्स्ट की पहचान की जा सकती है.
Handwriting Recognition API क्या है?
हैंडराइटिंग की पहचान करने वाले एपीआई की मदद से, उपयोगकर्ताओं की हैंडराइटिंग (स्याही) को टेक्स्ट में बदला जा सकता है. कुछ ऑपरेटिंग सिस्टम में, ऐसे एपीआई लंबे समय से शामिल हैं. इस नई सुविधा की मदद से, आपके वेब ऐप्लिकेशन आखिरकार इस सुविधा का इस्तेमाल कर सकते हैं. कन्वर्ज़न सीधे उपयोगकर्ता के डिवाइस पर होता है. यह ऑफ़लाइन मोड में भी काम करता है. इसके लिए, तीसरे पक्ष की लाइब्रेरी या सेवाओं को जोड़ने की ज़रूरत नहीं होती.
यह एपीआई, "ऑन-लाइन" या करीब-करीब रीयल-टाइम में पहचान करने की सुविधा देता है. इसका मतलब है कि उपयोगकर्ता जब लिख रहा होता है, तब ही लिखाई को पहचान लिया जाता है. इसके लिए, एक-एक स्ट्रोक को कैप्चर करके उसका विश्लेषण किया जाता है. ऑप्टिकल कैरेक्टर रिकग्निशन (ओसीआर) जैसी "ऑफ़-लाइन" प्रोसेस के मुकाबले, ऑन-लाइन एल्गोरिदम ज़्यादा सटीक नतीजे दे सकते हैं. ऐसा, अलग-अलग इंक स्ट्रोक के समय के क्रम और दबाव जैसे अतिरिक्त सिग्नल की वजह से होता है.
लिखावट की पहचान करने वाले एपीआई के इस्तेमाल के सुझाए गए उदाहरण
इस्तेमाल के उदाहरणों में ये शामिल हैं:
- नोट लेने वाले ऐसे ऐप्लिकेशन जिनमें उपयोगकर्ता, हाथ से लिखे गए नोट कैप्चर करके उन्हें टेक्स्ट में बदलना चाहते हैं.
- फ़ॉर्म वाले ऐसे ऐप्लिकेशन जहां समय की कमी की वजह से, उपयोगकर्ता पेन या उंगली से इनपुट कर सकते हैं.
- ऐसे गेम जिनमें अक्षर या नंबर भरना ज़रूरी होता है, जैसे कि क्रॉसवर्ड, हैंगमैन या सुडोकू.
मौजूदा स्थिति
लिखावट की पहचान करने वाला एपीआई, Chromium 99 से उपलब्ध है.
लिखावट की पहचान करने वाले एपीआई का इस्तेमाल करने का तरीका
सुविधा की पहचान
नेविगेटर ऑब्जेक्ट पर createHandwritingRecognizer()
तरीके के मौजूद होने की जांच करके, ब्राउज़र के साथ काम करने की सुविधा का पता लगाएं:
if ('createHandwritingRecognizer' in navigator) {
// 🎉 The Handwriting Recognition API is supported!
}
मुख्य कॉन्सेप्ट
हैंडराइटिंग की पहचान करने वाला एपीआई, हाथ से लिखे गए इनपुट को टेक्स्ट में बदलता है. भले ही, इनपुट का कोई भी तरीका (माउस, टच, पेन) हो. एपीआई में चार मुख्य इकाइयां होती हैं:
- पॉइंट यह दिखाता है कि किसी खास समय में पॉइंटर कहां था.
- स्ट्रोक में एक या उससे ज़्यादा पॉइंट होते हैं. स्ट्रोक की रिकॉर्डिंग तब शुरू होती है, जब उपयोगकर्ता कर्सर को नीचे रखता है. जैसे, माउस के प्राइमरी बटन पर क्लिक करना या स्क्रीन को अपनी उंगली या पैंसिल से छूना. यह रिकॉर्डिंग तब खत्म होती है, जब उपयोगकर्ता कर्सर को फिर से ऊपर ले जाता है.
- ड्रॉइंग में एक या एक से ज़्यादा स्ट्रोक होते हैं. असल पहचान इस लेवल पर होती है.
- आवाज़ पहचानने की सुविधा को, इनपुट भाषा के हिसाब से कॉन्फ़िगर किया गया है. इसका इस्तेमाल, पहचान करने वाले टूल के कॉन्फ़िगरेशन के साथ ड्रॉइंग का एक इंस्टेंस बनाने के लिए किया जाता है.
इन कॉन्सेप्ट को खास इंटरफ़ेस और डिक्शनरी के तौर पर लागू किया जाता है. इनके बारे में हम जल्द ही बताएंगे.
पहचानने वाला टूल बनाना
हाथ से लिखे गए इनपुट से टेक्स्ट की पहचान करने के लिए, आपको navigator.createHandwritingRecognizer()
को कॉल करके और उसमें कंस्ट्रेंट पास करके, HandwritingRecognizer
का एक इंस्टेंस पाना होगा. कंस्ट्रेंट, लिखावट की पहचान करने वाले उस मॉडल को तय करते हैं जिसका इस्तेमाल किया जाना चाहिए. फ़िलहाल, अपनी पसंद के हिसाब से भाषाओं की सूची बनाई जा सकती है:
const recognizer = await navigator.createHandwritingRecognizer({
languages: ['en'],
});
जब ब्राउज़र आपका अनुरोध पूरा कर सकता है, तब यह तरीका एक HandwritingRecognizer
के इंस्टेंस के साथ रिज़ॉल्व होने वाला एक प्रॉमिस दिखाता है. ऐसा न करने पर, यह गड़बड़ी के साथ वादा अस्वीकार कर देगा और लिखावट की पहचान करने की सुविधा उपलब्ध नहीं होगी. इस वजह से, हो सकता है कि आप पहले पहचान करने वाली खास सुविधाओं के लिए, आइडेंटिफ़ायर की सहायता से क्वेरी करना चाहें.
बोली पहचानने की सुविधा से जुड़ी सहायता के लिए क्वेरी करना
navigator.queryHandwritingRecognizerSupport()
को कॉल करके, यह देखा जा सकता है कि टारगेट प्लैटफ़ॉर्म पर, हैंडराइटिंग की पहचान करने की उन सुविधाओं का इस्तेमाल किया जा सकता है या नहीं जिनका आपको इस्तेमाल करना है. नीचे दिए गए उदाहरण में, डेवलपर:
- को अंग्रेज़ी में टेक्स्ट का पता लगाना है
- उपलब्ध होने पर, कम संभावना वाले अन्य अनुमान पाएं
- सेगमेंटेशन के नतीजे का ऐक्सेस पाएं. जैसे, पहचाने गए वर्णों के साथ-साथ, उन वर्णों को बनाने वाले पॉइंट और स्ट्रोक
const { languages, alternatives, segmentationResults } =
await navigator.queryHandwritingRecognizerSupport({
languages: ['en'],
alternatives: true,
segmentationResult: true,
});
console.log(languages); // true or false
console.log(alternatives); // true or false
console.log(segmentationResult); // true or false
यह तरीका, नतीजे के ऑब्जेक्ट के साथ रिज़ॉल्व होने वाला प्रॉमिस दिखाता है. अगर ब्राउज़र पर डेवलपर की बताई गई सुविधा काम करती है, तो इसकी वैल्यू true
पर सेट हो जाएगी. ऐसा न करने पर, यह false
पर सेट हो जाएगा.
इस जानकारी का इस्तेमाल करके, अपने ऐप्लिकेशन में कुछ सुविधाओं को चालू या बंद किया जा सकता है. इसके अलावा, अपनी क्वेरी में बदलाव करके नई क्वेरी भी भेजी जा सकती है.
ड्रॉइंग बनाना
आपको अपने ऐप्लिकेशन में एक इनपुट एरिया उपलब्ध कराना चाहिए, जहां उपयोगकर्ता अपनी लिखावट में जानकारी डाल सके. परफ़ॉर्मेंस की वजह से, हमारा सुझाव है कि इसे कैनवस ऑब्जेक्ट की मदद से लागू करें. इस लेख में, इस हिस्से को लागू करने का सटीक तरीका नहीं बताया गया है. हालांकि, इसे लागू करने का तरीका जानने के लिए, डेमो देखें.
नई ड्रॉइंग शुरू करने के लिए, आइडेंटिफ़ायर पर startDrawing()
तरीके को कॉल करें. यह तरीका पहचान के एल्गोरिदम को बेहतर बनाने के लिए,
अलग-अलग संकेतों वाले ऑब्जेक्ट को लेता है. सभी संकेत देने की ज़रूरत नहीं है:
- डाला जा रहा टेक्स्ट किस तरह का है: टेक्स्ट, ईमेल पते, नंबर या कोई एक वर्ण (
recognitionType
) - इनपुट डिवाइस का टाइप: माउस, टच या पेन इनपुट (
inputType
) - पिछला टेक्स्ट (
textContext
) - दिखाए जाने वाले वैकल्पिक अनुमानों की संख्या (
alternatives
) - उपयोगकर्ता की पहचान करने वाले उन वर्णों ("ग्राफ़िम") की सूची जिन्हें उपयोगकर्ता डाल सकता है
(
graphemeSet
)
हस्तलेखन की पहचान करने वाला एपीआई, पॉइंटर इवेंट के साथ बेहतर तरीके से काम करता है. ये इवेंट, किसी भी पॉइंटर डिवाइस से इनपुट लेने के लिए, एक एब्स्ट्रैक्ट इंटरफ़ेस उपलब्ध कराते हैं. पॉइंटर इवेंट आर्ग्युमेंट में, इस्तेमाल किए जा रहे पॉइंटर
का टाइप होता है. इसका मतलब है कि इनपुट टाइप का पता अपने-आप लगाने के लिए, पॉइंटर इवेंट का इस्तेमाल किया जा सकता है. नीचे दिए गए उदाहरण में, लिखावट की पहचान करने के लिए ड्रॉइंग, लिखावट वाले सेक्शन में pointerdown
इवेंट की पहली बार होने पर अपने-आप बन जाती है. pointerType
खाली हो सकता है या मालिकाना हक वाली वैल्यू पर सेट हो सकता है. इसलिए, मैंने एक जांच की सुविधा जोड़ी है, ताकि यह पक्का किया जा सके कि ड्रॉइंग के इनपुट टाइप के लिए सिर्फ़ काम करने वाली वैल्यू सेट की गई हों.
let drawing;
let activeStroke;
canvas.addEventListener('pointerdown', (event) => {
if (!drawing) {
drawing = recognizer.startDrawing({
recognitionType: 'text', // email, number, per-character
inputType: ['mouse', 'touch', 'pen'].find((type) => type === event.pointerType),
textContext: 'Hello, ',
alternatives: 2,
graphemeSet: ['f', 'i', 'z', 'b', 'u'], // for a fizz buzz entry form
});
}
startStroke(event);
});
स्ट्रोक जोड़ें
pointerdown
इवेंट, नया स्ट्रोक शुरू करने के लिए भी सही जगह है. ऐसा करने के लिए, HandwritingStroke
का नया उदाहरण बनाएं. साथ ही, आपको इसमें जोड़े गए आगे के पॉइंट के लिए, मौजूदा समय को रेफ़रंस के तौर पर सेव करना चाहिए:
function startStroke(event) {
activeStroke = {
stroke: new HandwritingStroke(),
startTime: Date.now(),
};
addPoint(event);
}
एक बिंदु जोड़ें
स्ट्रोक बनाने के बाद, आपको सीधे उसमें पहला पॉइंट जोड़ना चाहिए. बाद में आपको और भी पॉइंट जोड़ने होंगे. इसलिए, पॉइंट बनाने के लॉजिक को अलग तरीके से लागू करना बेहतर होगा. यहां दिए गए उदाहरण में, addPoint()
तरीका, रेफ़रंस टाइमस्टैंप से बीते हुए समय को कैलकुलेट करता है.
समय की जानकारी देना ज़रूरी नहीं है. हालांकि, इससे ऑब्जेक्ट की पहचान करने की क्वालिटी को बेहतर बनाया जा सकता है. इसके बाद, यह पॉइंटर इवेंट से X और Y निर्देशांक पढ़ता है और मौजूदा स्ट्रोक में पॉइंट जोड़ता है.
function addPoint(event) {
const timeElapsed = Date.now() - activeStroke.startTime;
activeStroke.stroke.addPoint({
x: event.offsetX,
y: event.offsetY,
t: timeElapsed,
});
}
जब पॉइंटर को स्क्रीन पर ले जाया जाता है, तब pointermove
इवेंट हैंडलर को कॉल किया जाता है. उन पॉइंट को भी स्ट्रोक में जोड़ना होगा. जब पॉइंटर "डाउन" स्थिति में न हो, तब भी इवेंट को दिखाया जा सकता है.
उदाहरण के लिए, माउस बटन को दबाए बिना कर्सर को स्क्रीन पर ले जाना. यहां दिए गए उदाहरण में, इवेंट हैंडलर यह जांच करता है कि कोई ऐक्टिव स्ट्रोक मौजूद है या नहीं. साथ ही, उसमें नया पॉइंट जोड़ता है.
canvas.addEventListener('pointermove', (event) => {
if (activeStroke) {
addPoint(event);
}
});
टेक्स्ट की पहचान करना
जब उपयोगकर्ता फिर से पॉइंटर हटाता है, तो addStroke()
तरीके को कॉल करके, अपने ड्रॉइंग में स्ट्रोक जोड़ा जा सकता है. यहां दिया गया उदाहरण activeStroke
को भी रीसेट करता है, इसलिए pointermove
हैंडलर, पूरे हुए स्ट्रोक में पॉइंट नहीं जोड़ेगा.
इसके बाद, ड्रॉइंग पर getPrediction()
तरीके को कॉल करके, उपयोगकर्ता के इनपुट की पहचान करने का समय आ गया है. आम तौर पर, पहचान करने में कुछ सौ मिलीसेकंड से भी कम समय लगता है. इसलिए, ज़रूरत पड़ने पर, अनुमान बार-बार चलाए जा सकते हैं. नीचे दिए गए उदाहरण में, हर स्ट्रोक के पूरा होने के बाद नया अनुमान लगाया जाता है.
canvas.addEventListener('pointerup', async (event) => {
drawing.addStroke(activeStroke.stroke);
activeStroke = null;
const [mostLikelyPrediction, ...lessLikelyAlternatives] = await drawing.getPrediction();
if (mostLikelyPrediction) {
console.log(mostLikelyPrediction.text);
}
lessLikelyAlternatives?.forEach((alternative) => console.log(alternative.text));
});
इस तरीके से प्रॉमिस प्रॉमिस होता है, जो उनके अनुमान के हिसाब से क्रम में लगाया जाता है. एलिमेंट की संख्या, alternatives
संकेत के लिए पास की गई वैल्यू पर निर्भर करती है. इस कलेक्शन का इस्तेमाल करके, उपयोगकर्ता को मिलते-जुलते विकल्प दिखाए जा सकते हैं. साथ ही, उनसे कोई विकल्प चुना जा सकता है. इसके अलावा, आप सबसे ज़्यादा संभावना वाले अनुमान को आज़मा सकते हैं. मैं उदाहरण के तौर पर
यही का ही इस्तेमाल करता हूँ.
अनुमान वाले ऑब्जेक्ट में, पहचाने गए टेक्स्ट के साथ-साथ सेगमेंटेशन का वैकल्पिक नतीजा भी शामिल होता है. इस बारे में अगले सेक्शन में बताया जाएगा.
सेगमेंटेशन के नतीजों के साथ ज़्यादा जानकारी
अगर टारगेट प्लैटफ़ॉर्म पर सेगमेंटेशन की सुविधा काम करती है, तो अनुमान वाले ऑब्जेक्ट में सेगमेंटेशन का नतीजा भी शामिल हो सकता है.
यह एक कलेक्शन है, जिसमें पहचाने गए सभी हैंडराइटिंग सेगमेंट शामिल होते हैं. यह पहचाने गए ऐसे वर्ण (grapheme
) का कॉम्बिनेशन होता है जिसे उपयोगकर्ता पहचान सकता है. साथ ही, इसमें पहचाने गए टेक्स्ट (beginIndex
, endIndex
) में इसकी पोज़िशन और इसे बनाने वाले स्ट्रोक और पॉइंट शामिल होते हैं.
if (mostLikelyPrediction.segmentationResult) {
mostLikelyPrediction.segmentationResult.forEach(
({ grapheme, beginIndex, endIndex, drawingSegments }) => {
console.log(grapheme, beginIndex, endIndex);
drawingSegments.forEach(({ strokeIndex, beginPointIndex, endPointIndex }) => {
console.log(strokeIndex, beginPointIndex, endPointIndex);
});
},
);
}
इस जानकारी का इस्तेमाल करके, कैनवस पर पहचाने गए ग्रैफ़ेम को फिर से ट्रैक किया जा सकता है.
पहचान की पुष्टि करना
पहचान की प्रक्रिया पूरी होने के बाद, संसाधनों को मुफ़्त में इस्तेमाल किया जा सकेगा. इसके लिए, HandwritingDrawing
पर clear()
तरीके को कॉल करें और HandwritingRecognizer
पर finish()
तरीके का इस्तेमाल करें:
drawing.clear();
recognizer.finish();
डेमो
वेब कॉम्पोनेंट <handwriting-textarea>
में क्रम से बेहतर सेटिंग लागू की गई है. इसमें हैंडराइटिंग की पहचान करने वाला बदलाव करने का कंट्रोल भी शामिल है. बदलाव करने के कंट्रोल के सबसे नीचे दाएं कोने में मौजूद बटन पर क्लिक करके, ड्रॉइंग मोड चालू किया जा सकता है. ड्रॉइंग पूरी करने के बाद, वेब कॉम्पोनेंट अपने-आप टेक्स्ट की पहचान करने की प्रोसेस शुरू कर देगा और पहचाने गए टेक्स्ट को, बदलाव करने वाले कंट्रोल में वापस जोड़ देगा. अगर आपके डिवाइस पर, लिखावट पहचानने वाले एपीआई का इस्तेमाल नहीं किया जा सकता या प्लैटफ़ॉर्म पर अनुरोध की गई सुविधाएं काम नहीं करती हैं, तो 'बदलाव करें' बटन नहीं दिखेगा. हालांकि, बदलाव करने के बुनियादी कंट्रोल का इस्तेमाल <textarea>
के तौर पर किया जा सकता है.
वेब कॉम्पोनेंट, languages
और recognitiontype
के साथ-साथ, बाहर से पहचान करने के व्यवहार को तय करने के लिए प्रॉपर्टी और एट्रिब्यूट उपलब्ध कराता है. कंट्रोल का कॉन्टेंट सेट करने के लिए,
value
एट्रिब्यूट का इस्तेमाल करें:
<handwriting-textarea languages="en" recognitiontype="text" value="Hello"></handwriting-textarea>
वैल्यू में हुए किसी भी बदलाव के बारे में जानने के लिए, input
इवेंट को सुना जा सकता है.
Glitch पर इस डेमो का इस्तेमाल करके, कॉम्पोनेंट को आज़माया जा सकता है. साथ ही, सोर्स कोड पर नज़र डालना न भूलें. अपने ऐप्लिकेशन में कंट्रोल का इस्तेमाल करने के लिए, इसे npm से पाएं.
सुरक्षा और अनुमतियां
Chromium टीम ने वेब प्लैटफ़ॉर्म की बेहतर सुविधाओं का ऐक्सेस कंट्रोल करना में बताए गए मुख्य सिद्धांतों का इस्तेमाल करके, लिखावट पहचानने वाले एपीआई को डिज़ाइन और लागू किया है. इन सिद्धांतों में, उपयोगकर्ता कंट्रोल, पारदर्शिता, और काम करने के तरीके शामिल हैं.
ऐप्लिकेशन पर उपयोगकर्ताओं के कंट्रोल की जानकारी
उपयोगकर्ता, हैंडराइटिंग की पहचान करने वाले एपीआई को बंद नहीं कर सकता. यह सिर्फ़ एचटीटीपीएस के ज़रिए डिलीवर की जाने वाली वेबसाइटों के लिए उपलब्ध है. साथ ही, इसे सिर्फ़ टॉप-लेवल ब्राउज़िंग कॉन्टेक्स्ट से कॉल किया जा सकता है.
पारदर्शिता
हैंडराइटिंग की पहचान करने की सुविधा चालू होने पर, इसकी कोई जानकारी नहीं मिलती. फ़िंगरप्रिंटिंग को रोकने के लिए, ब्राउज़र कई तरह के उपाय करता है. जैसे, संभावित गलत इस्तेमाल का पता चलने पर, उपयोगकर्ता को अनुमति का अनुरोध दिखाना.
अनुमति का जारी रहना
फ़िलहाल, लिखावट पहचानने की सुविधा देने वाला एपीआई, अनुमतियों के लिए कोई प्रॉम्प्ट नहीं दिखाता. इसलिए, अनुमति को किसी भी तरह से बनाए रखने की ज़रूरत नहीं होती.
सुझाव/राय दें या शिकायत करें
Chromium की टीम, लिखावट पहचानने वाले एपीआई के साथ आपके अनुभवों के बारे में जानना चाहती है.
हमें एपीआई के डिज़ाइन के बारे में बताएं
क्या एपीआई में ऐसा कुछ है जो आपकी उम्मीद के मुताबिक काम नहीं करता? क्या आपके आइडिया को लागू करने के लिए, कोई तरीका या प्रॉपर्टी मौजूद नहीं है? क्या आपका सुरक्षा मॉडल के बारे में कोई सवाल या टिप्पणी है? इससे जुड़े GitHub रेपो पर, कोई खास समस्या दर्ज करें या किसी मौजूदा समस्या के बारे में अपनी राय दें.
लागू करने से जुड़ी समस्या की शिकायत करना
क्या आपको Chromium को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, खास जानकारी से अलग है?
new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें. इसके बाद, Components बॉक्स में Blink>Handwriting
डालें.
Glitch, तुरंत और आसानी से समस्या की जानकारी शेयर करने के लिए बहुत अच्छा है.
एपीआई के लिए सहायता दिखाना
क्या आपको हैंडराइटिंग की पहचान करने वाला एपीआई इस्तेमाल करना है? सार्वजनिक तौर पर सहायता करने से, Chromium टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे ब्राउज़र के अन्य वेंडर को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है.
WICG के Discourse थ्रेड पर बताएं कि आपको इसका इस्तेमाल कैसे करना है. #HandwritingRecognition
हैशटैग का इस्तेमाल करके, @ChromiumDev को ट्वीट करें और हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.
सहायक लिंक्स
- एक्सप्लेनर
- स्पेसिफ़िकेशन का ड्राफ़्ट
- GitHub का डेटा स्टोर
- ChromeStatus
- Chromium में गड़बड़ी
- टैग की समीक्षा
- प्रोटोटाइप बनाने का मकसद
- WebKit-Dev थ्रेड
- Mozilla के स्टैंडर्ड की स्थिति
धन्यवाद
इस दस्तावेज़ की समीक्षा जो मेडली, हॉन्गलिन यू, और ज़िएवी कियान ने की है.