Image and text captcha OCR: วิธีอ่าน captcha ที่บิดเบี้ยว
image captcha แสดงตัวอักษรหรือตัวเลขสั้น ๆ เป็นภาพ บางครั้งมีสัญญาณรบกวน การหมุน และเส้นคลื่น Optical character recognition (OCR) สามารถอ่านรูปแบบที่ง่ายของ captcha เหล่านี้ได้ด้วยเอนจินโอเพนซอร์สอย่าง Tesseract ความแม่นยำขึ้นกับความสะอาดของภาพ ดังนั้นงานส่วนใหญ่คือการเตรียมภาพ คู่มือนี้แสดงการตั้งค่า Python ที่ใช้งานได้จริง อธิบายว่ามันล้มเหลวตรงไหน และชี้ให้เห็นชัดเจนว่า API ที่ใช้งานจริงของ Scarnox แก้ token ของ PopularCaptcha widget ไม่ใช่ captcha แบบภาพเป็นข้อความ ดังนั้นให้วางแผน OCR เป็นโค้ดของคุณเอง ไม่ใช่การเรียก API
เมื่อไรที่ OCR ใช้ได้และเมื่อไรที่ไม่ได้
OCR เป็นตัวเลือกแรกที่สมเหตุสมผลเมื่อข้อความ:
- อยู่บรรทัดเดียว มีระยะห่างสม่ำเสมอ
- มีความต่างของสีสูง ตัวอักษรเข้มบนพื้นหลังสว่าง
- ไม่มีการบิดเบี้ยวมาก ตัวอักษรไม่ซ้อนทับกัน และไม่มีเส้นตัดผ่าน
OCR จะลำบากกับตัวอักษรที่หมุน ตัวอักษรที่แตะกัน พื้นหลังที่มีลวดลาย และเส้นที่ลากผ่านตัวอักษร แต่ละกรณีต้องมีขั้นตอนการเตรียมภาพเฉพาะ และบางกรณีต้องใช้โมเดลอีกประเภทไปเลย เตรียมพร้อมที่จะวัดความแม่นยำ อย่าสมมติว่ามันแม่นยำเอง
ติดตั้งเครื่องมือ
คุณต้องมี Python, ไบนารี Tesseract และแพ็กเกจ Python อีกสองตัว:
pip install pillow pytesseract
Tesseract เป็นการติดตั้งแยกต่างหาก บน Windows ให้ใช้ installer จากโปรเจกต์ Tesseract และตรวจว่าไฟล์ที่รันได้อยู่ใน PATH หรือไม่ หรือไม่ก็ชี้ pytesseract.pytesseract.tesseract_cmd ไปที่ไฟล์นั้น
เตรียมภาพ แล้วอ่าน
ความแม่นยำส่วนใหญ่มาจากข้อมูลนำเข้าที่สะอาด ลำดับด้านล่างแปลงเป็น grayscale เพิ่ม contrast ใช้ threshold แบบตายตัว ขยายภาพ และจำกัดผลลัพธ์ให้เหลือเฉพาะตัวอักษรที่ captcha ใช้:
from PIL import Image, ImageOps
import pytesseract
# ตัวอักษรที่ captcha ใช้ได้ ตัดตัวที่หน้าตาคล้ายกันออก เช่น 0/O และ 1/I หาก captcha ไม่ได้ใช้ตัวเหล่านั้น
ALLOWED = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
def read_text(path: str) -> str:
img = Image.open(path)
gray = ImageOps.grayscale(img)
gray = ImageOps.autocontrast(gray)
# Threshold แบบตายตัว: พิกเซลที่สว่างกว่า 140 จะเป็นสีขาว ส่วนที่เหลือเป็นสีดำ
bw = gray.point(lambda p: 255 if p > 140 else 0)
# Tesseract ทำงานได้ดีขึ้นกับตัวอักษรที่ใหญ่กว่า
bw = bw.resize((bw.width * 3, bw.height * 3))
config = f"--psm 7 -c tessedit_char_whitelist={ALLOWED}" # psm 7: ข้อความหนึ่งบรรทัด
return pytesseract.image_to_string(bw, config=config).strip()
if __name__ == "__main__":
print(read_text("sample_captcha.png"))
ค่า threshold 140 เป็นจุดเริ่มต้น ให้พิมพ์ภาพที่ผ่านการประมวลผลแล้ว เทียบกับภาพต้นฉบับ และปรับจนตัวอักษรชัดเจนและพื้นหลังสะอาด
วัดความแม่นยำก่อนพึ่งพา
การอ่านถูกหนึ่งครั้งจากภาพหนึ่งภาพไม่ได้พิสูจน์อะไร เก็บชุด captcha ที่รู้คำตอบอยู่แล้ว รันฟังก์ชันกับทุกภาพ แล้วนับจำนวนที่ตรง:
def accuracy(samples: dict[str, str]) -> float:
# samples เป็น mapping จาก path ของไฟล์ไปยังข้อความจริง
hits = sum(read_text(path) == truth for path, truth in samples.items())
return hits / len(samples)
labelled = {
"samples/0001.png": "K7PQ2",
"samples/0002.png": "M3XN9",
}
print(f"accuracy: {accuracy(labelled):.0%}")
ติดตามตัวเลขนี้ทุกครั้งที่เปลี่ยนขั้นตอนการเตรียมภาพ ถ้าตัวเลขยังต่ำหลังจากปรับหลายครั้ง OCR อาจเป็นเครื่องมือที่ผิดสำหรับรูปแบบ captcha นั้น และคุณควรมองหาวิธีอื่น
จุดที่มันพัง
- สัญญาณรบกวนและเส้น ลบเส้นด้วย morphological operation หรือยอมรับอัตราที่ต่ำลง
- การหมุน ประมาณมุมแล้วหมุนภาพก่อนอ่าน
- ตัวอักษรที่แตะกัน การแยกตัวอักษรตามคอลัมน์แล้วอ่านทีละตัวมักได้ผลดีกว่าการอ่านทั้งบรรทัด
- การเปลี่ยนแปลงตามเวลา เว็บไซต์อาจเปลี่ยนรูปแบบโดยไม่แจ้งล่วงหน้า ทำให้ความแม่นยำตกภายในข้ามคืน เก็บชุดที่มีคำตอบกำกับไว้ และรันซ้ำเป็นประจำ
checklist การเตรียมภาพ
เมื่ออ่านไม่สำเร็จ ให้ไล่ตรวจตามลำดับนี้ เปลี่ยนทีละอย่าง เพื่อให้เห็นว่าขั้นตอนไหนช่วย:
- ตรวจขนาดของข้อมูลนำเข้า captcha ที่เล็กมากมักอ่านได้ดีขึ้นหลังขยาย 3 เท่า
- แปลงเป็น grayscale และยืด contrast เพื่อให้ตัวอักษรเด่นขึ้น
- ใช้ threshold ลองค่าหลายค่าก่อนเลือกค่าหนึ่ง
- ลด speckle noise ด้วย median filter แล้ว threshold ใหม่หากจำเป็น
- ครอปภาพให้เหลือเฉพาะพื้นที่ข้อความ เพื่อไม่ให้พื้นหลังทำให้เอนจินสับสน
- จำกัดชุดตัวอักษรให้เหลือเฉพาะที่ captcha ใช้
- ลอง page segmentation mode อื่นหากข้อความกระจายหรือซ้อนกันเป็นชั้น
เก็บลำดับและการตั้งค่าไว้ใน version control ควบคู่กับตัวอย่างที่มีป้ายกำกับ pipeline การเตรียมข้อมูลคือโค้ด และควรถูก review เหมือนโค้ด
OCR หรือโมเดลที่คุณรันเอง
OCR แบบคลาสสิกเร็วและรันบนแล็ปท็อปได้ แต่เปราะบางเมื่อ captcha เปลี่ยนรูปแบบ โมเดลภาพที่ฝึกจากชุดข้อมูลที่มีป้ายกำกับของคุณเองรับมือความหลากหลายได้มากกว่า แลกกับการเก็บข้อมูลและการรัน inference ทั้งสองแบบเป็นความรับผิดชอบของคุณในการสร้างและดูแล ตอนนี้ไม่มี endpoint ของ Scarnox ที่โฮสต์ไว้ให้ ดังนั้นวางแผนโครงสร้างพื้นฐานก่อนตัดสินใจ
Scarnox ทำอะไรและไม่ทำอะไรในส่วนนี้
API ที่ใช้งานได้จริงของ Scarnox แก้ token ของ PopularCaptcha widget คำขอคือ POST https://api.scarnox.com/api/tasks/create พร้อมประเภท task PopularCaptcha, sitekey และ URL ของหน้า แล้วการตอบกลับคือ token สำหรับฟิลด์ของฟอร์ม นั่นเป็นงานคนละอย่างกับการอ่านตัวอักษรในภาพ และ Scarnox ไม่มี endpoint แบบภาพเป็นข้อความในตอนนี้ ถ้าปัญหาของคุณคือ image captcha ให้ใช้ OCR หรือโมเดลที่คุณรันเอง และดูคู่มืออื่นเพื่อดูว่า Scarnox ครอบคลุมอะไรบ้าง คุณสามารถ สร้างบัญชี และเริ่มด้วยเครดิตทดลองใช้ฟรี ไม่ต้องใช้บัตรเครดิต สำหรับ flow ของ PopularCaptcha ที่รองรับ ราคาปัจจุบัน อยู่ในหน้าราคา
การใช้งานที่ถูกต้องตามกฎหมาย
- อ่านข้อความจากเอกสารที่สแกน ภาพหน้าจอ หรือภาพทดสอบของคุณเอง
- เครื่องมือ accessibility ที่อธิบายหรืออ่าน captcha เพื่อให้ผู้ใช้ที่มีความบกพร่องทางการมองเห็นใช้เส้นทางทางเลือกที่เว็บไซต์จัดให้
- ทดสอบการออกแบบ captcha ของคุณเอง เพื่อดูว่าเครื่องมืออัตโนมัติอ่านได้ง่ายแค่ไหน แล้วทำให้มันแข็งแรงขึ้น
อย่าใช้ OCR เพื่อผ่าน captcha บนเว็บไซต์ที่ไม่อนุญาตให้เข้าถึงแบบอัตโนมัติ image captcha มีอยู่เพื่อชะลอการใช้งานแบบนั้นโดยเฉพาะ