py2ls 0.2.4.32__py3-none-any.whl → 0.2.4.33__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
py2ls/netfinder.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from bs4 import BeautifulSoup
2
+ import scrapy
2
3
  import requests
3
4
  import os
4
5
  import pandas as pd
@@ -332,6 +333,94 @@ def parse_cookies(cookies_str):
332
333
 
333
334
  return cookies_dict
334
335
 
336
+ class FetchSpider(scrapy.Spider):
337
+ name = "fetch_spider"
338
+
339
+ def __init__(self, url, parser="html.parser", cookies=None, headers=None, *args, **kwargs):
340
+ super(FetchSpider, self).__init__(*args, **kwargs)
341
+ self.start_urls = [url]
342
+ self.cookies = cookies
343
+ self.headers = headers
344
+ self.parser = parser
345
+
346
+ def start_requests(self):
347
+ for url in self.start_urls:
348
+ yield scrapy.Request(
349
+ url,
350
+ cookies=self.cookies,
351
+ headers=self.headers,
352
+ callback=self.parse
353
+ )
354
+
355
+ def parse(self, response):
356
+ # Use the desired parser (default: html.parser)
357
+ from bs4 import BeautifulSoup
358
+ soup = BeautifulSoup(response.text, self.parser)
359
+ yield {"content": soup}
360
+
361
+
362
+ def fetch_scrapy(
363
+ url,
364
+ parser="html.parser",
365
+ cookies=None,
366
+ headers=None,
367
+ settings=None,
368
+ ):
369
+ """
370
+ Fetches content using Scrapy.
371
+
372
+ Args:
373
+ url (str): The URL to scrape.
374
+ parser (str): Parser for BeautifulSoup (e.g., "lxml", "html.parser").
375
+ cookies (dict): Cookies to pass in the request.
376
+ headers (dict): HTTP headers for the request.
377
+ settings (dict): Scrapy settings, if any.
378
+
379
+ Returns:
380
+ dict: Parsed content as a dictionary.
381
+ """
382
+ from scrapy.utils.project import get_project_settings
383
+ from scrapy.crawler import CrawlerProcess
384
+ from scrapy.signalmanager import dispatcher
385
+ from scrapy import signals
386
+ import scrapy
387
+
388
+ # Container for scraped content
389
+ content = []
390
+
391
+ # Callback function for item scraped signal
392
+ def handle_item(item, response, spider):
393
+ content.append(item["content"])
394
+
395
+ # Scrapy settings
396
+ process_settings = settings or get_project_settings()
397
+ process_settings.update(
398
+ {
399
+ "USER_AGENT": "CustomUserAgent/1.0", # Use a custom user agent
400
+ "DOWNLOAD_DELAY": 1, # Prevent overloading servers
401
+ "COOKIES_ENABLED": bool(cookies),
402
+ "LOG_LEVEL": "ERROR", # Minimize log verbosity
403
+ }
404
+ )
405
+
406
+ # Initialize and configure Scrapy process
407
+ process = CrawlerProcess(settings=process_settings)
408
+ dispatcher.connect(handle_item, signal=signals.item_scraped)
409
+
410
+ # Start the Scrapy crawl
411
+ process.crawl(
412
+ FetchSpider,
413
+ url=url,
414
+ parser=parser,
415
+ cookies=cookies,
416
+ headers=headers,
417
+ )
418
+ process.start() # Blocks until all crawls are finished
419
+
420
+ # Return the first scraped content or None if empty
421
+ return content[0] if content else None
422
+
423
+
335
424
  def fetch_all(
336
425
  url,
337
426
  parser="lxml",
@@ -558,6 +647,16 @@ def fetch_all(
558
647
  else:
559
648
  logger.warning("Selenium could not fetch content")
560
649
  return None, None
650
+ elif 'scr' in driver.lower():
651
+ settings = {
652
+ "USER_AGENT": user_agent(),
653
+ "DOWNLOAD_DELAY": 1, # Prevent overloading the server
654
+ "COOKIES_ENABLED": True if cookies else False,
655
+ "LOG_LEVEL": "WARNING", # Reduce log verbosity
656
+ }
657
+ content=fetch_scrapy(url, parser=parser, cookies=cookies, headers=headers, settings=settings)
658
+ return parser, content
659
+
561
660
  except requests.RequestException as e:
562
661
  logger.error(f"Error fetching URL '{url}': {e}")
563
662
  return None, None
py2ls/ocr.py CHANGED
@@ -1,23 +1,16 @@
1
- import easyocr
1
+
2
2
  import cv2
3
3
  import numpy as np
4
4
  import matplotlib.pyplot as plt
5
5
  from py2ls.ips import (
6
6
  strcmp,
7
7
  detect_angle,
8
- ) # Ensure this function is defined in your 'ips' module
9
- from spellchecker import SpellChecker
10
- import re
11
-
12
- from PIL import Image, ImageDraw, ImageFont
13
- import PIL.PngImagePlugin
14
- import pytesseract
15
- from paddleocr import PaddleOCR
8
+ str2words,
9
+ isa
10
+ )
16
11
  import logging
17
-
18
- logging.getLogger("ppocr").setLevel(
19
- logging.WARNING
20
- ) # or logging.ERROR to show only error messages
12
+ #logging.getLogger("ppocr").setLevel(logging.ERROR)
13
+ logging.getLogger("ppocr").setLevel(logging.WARNING)
21
14
 
22
15
  """
23
16
  Optical Character Recognition (OCR)
@@ -285,10 +278,12 @@ def add_text_pil(
285
278
  image,
286
279
  text,
287
280
  position,
281
+ cvt_cmp=True,
288
282
  font_size=12,
289
283
  color=(0, 0, 0),
290
284
  bg_color=(133, 203, 245, 100),
291
285
  ):
286
+ from PIL import Image, ImageDraw, ImageFont
292
287
  # Convert the image to PIL format
293
288
  pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)).convert("RGBA")
294
289
  # Define the font (make sure to use a font that supports Chinese characters)
@@ -337,7 +332,7 @@ def add_text_pil(
337
332
  overlay = overlay.convert("RGBA")
338
333
  combined = Image.alpha_composite(pil_image, overlay)
339
334
  # Convert the image back to OpenCV format
340
- image = cv2.cvtColor(np.array(combined), cv2.COLOR_RGBA2BGR)
335
+ image = cv2.cvtColor(np.array(combined), cv2.COLOR_RGBA2BGR) #if cvt_cmp else np.array(combined)
341
336
  return image
342
337
 
343
338
 
@@ -348,7 +343,7 @@ def preprocess_img(
348
343
  threshold_method="adaptive",
349
344
  rotate="auto",
350
345
  skew=False,
351
- blur=True,
346
+ blur=False,#True,
352
347
  blur_ksize=(5, 5),
353
348
  morph=True,
354
349
  morph_op="open",
@@ -384,12 +379,14 @@ def preprocess_img(
384
379
  clahe_grid_size: CLAHE 的网格大小。
385
380
  edge_detection: 是否进行边缘检测。
386
381
  """
382
+ import PIL.PngImagePlugin
387
383
  if isinstance(image, PIL.PngImagePlugin.PngImageFile):
388
384
  image = np.array(image)
389
385
  if isinstance(image, str):
390
386
  image = cv2.imread(image)
391
387
  if not isinstance(image, np.ndarray):
392
388
  image = np.array(image)
389
+
393
390
  try:
394
391
  if image.shape[1] == 4: # Check if it has an alpha channel
395
392
  # Drop the alpha channel (if needed), or handle it as required
@@ -507,6 +504,8 @@ def text_postprocess(
507
504
  pattern=None,
508
505
  merge=True,
509
506
  ):
507
+ import re
508
+ from spellchecker import SpellChecker
510
509
 
511
510
  def correct_spelling(text_list):
512
511
  spell = SpellChecker()
@@ -531,9 +530,9 @@ def text_postprocess(
531
530
  return merged_text
532
531
 
533
532
  results = text
534
- print(results)
535
533
  if spell_check:
536
- results = correct_spelling(results)
534
+ # results = correct_spelling(results)
535
+ results=str2words(results)
537
536
  if clean:
538
537
  results = clean_text(results)
539
538
  if filter:
@@ -552,42 +551,39 @@ def get_text(
552
551
  image,
553
552
  lang=["ch_sim", "en"],
554
553
  model="paddleocr", # "pytesseract","paddleocr","easyocr"
555
- thr=0.1,
554
+ thr=0.1,
556
555
  gpu=True,
557
556
  decoder="wordbeamsearch", #'greedy', 'beamsearch' and 'wordbeamsearch'(hightly accurate)
558
557
  output="txt",
559
558
  preprocess=None,
560
- postprocess="not ready",
559
+ postprocess=False,# do not check spell
561
560
  show=True,
562
561
  ax=None,
563
562
  cmap=cv2.COLOR_BGR2RGB, # draw_box
564
- font=cv2.FONT_HERSHEY_SIMPLEX,
565
- font_scale=0.8,
566
- thickness_text=2, # Line thickness of 2 px
567
- box_color=(0, 255, 0), # draw_box
568
- font_color=(0, 0, 0),
569
- bg_color=(133, 203, 245, 100),
563
+ font=cv2.FONT_HERSHEY_SIMPLEX,# draw_box
564
+ fontsize=8,# draw_box
565
+ figsize=[10,10],
566
+ box_color = (0, 255, 0), # draw_box
567
+ fontcolor = (0, 0, 0),# draw_box
568
+ bg_color=(133, 203, 245, 100),# draw_box
570
569
  usage=False,
571
570
  **kwargs,
572
571
  ):
573
572
  """
574
- 功能: 该函数使用 EasyOCR 进行文本识别,并允许自定义图像预处理步骤和结果展示。
575
- 参数:
576
- image: 输入的图像路径或图像数据。
577
- lang: OCR 语言列表。
578
- thr: 置信度阈值,低于此阈值的检测结果将被过滤。
579
- gpu: 是否使用 GPU。
580
- output: 输出类型,可以是 'all'(返回所有检测结果)、'text'(返回文本)、'score'(返回置信度分数)、'box'(返回边界框)。
581
- preprocess: 预处理参数字典,传递给 preprocess_img 函数。
582
- show: 是否显示结果图像。
583
- ax: 用于显示图像的 Matplotlib 子图。
584
- cmap: 用于显示图像的颜色映射。
585
- box_color: 边界框的颜色。
586
- font_color: 文本的颜色。
587
- kwargs: 传递给 EasyOCR readtext 函数的其他参数。
588
-
589
- # Uage
573
+ image: 输入的图像路径或图像数据。
574
+ lang: OCR 语言列表。
575
+ thr: 置信度阈值,低于此阈值的检测结果将被过滤。
576
+ gpu: 是否使用 GPU。
577
+ output: 输出类型,可以是 'all'(返回所有检测结果)、'text'(返回文本)、'score'(返回置信度分数)、'box'(返回边界框)。
578
+ preprocess: 预处理参数字典,传递给 preprocess_img 函数。
579
+ show: 是否显示结果图像。
580
+ ax: 用于显示图像的 Matplotlib 子图。
581
+ cmap: 用于显示图像的颜色映射。
582
+ box_color: 边界框的颜色。
583
+ fontcolor: 文本的颜色。
584
+ kwargs: 传递给 EasyOCR readtext 函数的其他参数。
590
585
  """
586
+ from PIL import Image
591
587
  if usage:
592
588
  print(
593
589
  """
@@ -612,16 +608,20 @@ def get_text(
612
608
  "edge_detection": False
613
609
  },
614
610
  adjust_contrast=0.7
615
- )
616
- """
617
- )
611
+ )""")
618
612
 
619
- models = ["easyocr", "paddleocr", "pytesseract","ddddocr"]
613
+ models = ["easyocr", "paddleocr", "pytesseract","ddddocr","zerox"]
620
614
  model = strcmp(model, models)[0]
621
615
  lang = lang_auto_detect(lang, model)
622
- if isinstance(image, str):
623
- dir_img=image
616
+ cvt_cmp=True
617
+ if isinstance(image, str) and isa(image,'file'):
624
618
  image = cv2.imread(image)
619
+ elif isa(image,'image'):
620
+ cvt_cmp=False
621
+ print(1)
622
+ image = np.array(image)
623
+ else:
624
+ raise ValueError(f"not support image with {type(image)} type")
625
625
 
626
626
  # Ensure lang is always a list
627
627
  if isinstance(lang, str):
@@ -631,110 +631,94 @@ def get_text(
631
631
  if preprocess is None:
632
632
  preprocess = {}
633
633
  image_process = preprocess_img(image, **preprocess)
634
+ plt.figure(figsize=figsize) if show else None
635
+ # plt.subplot(131)
636
+ # plt.imshow(cv2.cvtColor(image, cmap)) if cvt_cmp else plt.imshow(image)
637
+ # plt.subplot(132)
638
+ # plt.imshow(image_process)
639
+ # plt.subplot(133)
634
640
  if "easy" in model.lower():
641
+ import easyocr
635
642
  print(f"detecting language(s):{lang}")
636
643
  # Perform OCR on the image
637
644
  reader = easyocr.Reader(lang, gpu=gpu)
638
645
  detections = reader.readtext(image_process, decoder=decoder, **kwargs)
639
- if postprocess is None:
640
- postprocess = dict(
641
- spell_check=True,
642
- clean=True,
643
- filter=dict(min_length=2),
644
- pattern=None,
645
- merge=True,
646
- )
647
- text_corr = []
648
- [
649
- text_corr.extend(text_postprocess(text, **postprocess))
650
- for _, text, _ in detections
651
- ]
646
+
647
+ text_corr = []
648
+ for _, text, _ in detections:
649
+ text_corr.append(text_postprocess(text) if postprocess else text)
650
+
652
651
  if show:
653
652
  if ax is None:
654
653
  ax = plt.gca()
655
- for bbox, text, score in detections:
654
+ for i, (bbox, text, score) in enumerate(detections):
656
655
  if score > thr:
657
656
  top_left = tuple(map(int, bbox[0]))
658
657
  bottom_right = tuple(map(int, bbox[2]))
659
- image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
660
- # image = cv2.putText(
661
- # image, text, top_left, font, font_scale, font_color, thickness_text
662
- # )
658
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
663
659
  image = add_text_pil(
664
660
  image,
665
- text,
661
+ text_corr[i],
666
662
  top_left,
667
- font_size=font_scale * 32,
668
- color=font_color,
663
+ cvt_cmp=cvt_cmp,
664
+ font_size=fontsize *6,
665
+ color=fontcolor,
669
666
  )
670
- # img_cmp = cv2.cvtColor(image, cmap)
671
- ax.imshow(image)
667
+ try:
668
+ img_cmp = cv2.cvtColor(image, cmap) if cvt_cmp else image
669
+ except:
670
+ img_cmp=image
671
+
672
+ ax.imshow(img_cmp) if cvt_cmp else ax.imshow(image)
672
673
  ax.axis("off")
673
- # plt.show()
674
- # 根据输出类型返回相应的结果
674
+
675
675
  if output == "all":
676
676
  return ax, detections
677
677
  elif "t" in output.lower() and "x" in output.lower():
678
- # 提取文本,过滤低置信度的结果
679
678
  text = [text_ for _, text_, score_ in detections if score_ >= thr]
680
679
  if postprocess:
681
680
  return ax, text
682
681
  else:
683
682
  return text_corr
684
683
  elif "score" in output.lower() or "prob" in output.lower():
685
- # 提取分数
686
684
  scores = [score_ for _, _, score_ in detections]
687
685
  return ax, scores
688
686
  elif "box" in output.lower():
689
- # 提取边界框,过滤低置信度的结果
690
687
  bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
691
688
  return ax, bboxes
692
689
  else:
693
- # 默认返回所有检测信息
694
690
  return ax, detections
695
691
  else:
696
- # 根据输出类型返回相应的结果
697
692
  if output == "all":
698
693
  return detections
699
694
  elif "t" in output.lower() and "x" in output.lower():
700
- # 提取文本,过滤低置信度的结果
701
695
  text = [text_ for _, text_, score_ in detections if score_ >= thr]
702
696
  return text
703
697
  elif "score" in output.lower() or "prob" in output.lower():
704
- # 提取分数
705
698
  scores = [score_ for _, _, score_ in detections]
706
699
  return scores
707
700
  elif "box" in output.lower():
708
- # 提取边界框,过滤低置信度的结果
709
701
  bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
710
702
  return bboxes
711
703
  else:
712
- # 默认返回所有检测信息
713
704
  return detections
714
705
  elif "pad" in model.lower():
706
+ from paddleocr import PaddleOCR
707
+ lang=strcmp(lang, ['ch','en','french','german','korean','japan'])[0]
715
708
  ocr = PaddleOCR(
716
709
  use_angle_cls=True,
717
710
  cls=True,
711
+ lang=lang
718
712
  ) # PaddleOCR supports only one language at a time
719
- result = ocr.ocr(image_process, **kwargs)
713
+ cls=kwargs.pop('cls',True)
714
+ result = ocr.ocr(image_process,cls=cls, **kwargs)
720
715
  detections = []
721
716
  if result[0] is not None:
722
717
  for line in result[0]:
723
718
  bbox, (text, score) = line
719
+ text = str2words(text) if postprocess else text # check spell
724
720
  detections.append((bbox, text, score))
725
- if postprocess is None:
726
- postprocess = dict(
727
- spell_check=True,
728
- clean=True,
729
- filter=dict(min_length=2),
730
- pattern=None,
731
- merge=True,
732
- )
733
- text_corr = []
734
- [
735
- text_corr.extend(text_postprocess(text, **postprocess))
736
- for _, text, _ in detections
737
- ]
721
+
738
722
  if show:
739
723
  if ax is None:
740
724
  ax = plt.gca()
@@ -746,60 +730,48 @@ def get_text(
746
730
  ) # Bottom-left for more accurate placement
747
731
  bottom_right = tuple(map(int, bbox[2]))
748
732
  image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
749
- # image = cv2.putText(
750
- # image, text, top_left, font, font_scale, font_color, thickness_text
751
- # )
752
733
  image = add_text_pil(
753
734
  image,
754
735
  text,
755
736
  top_left,
756
- font_size=font_scale * 32,
757
- color=font_color,
737
+ cvt_cmp=cvt_cmp,
738
+ font_size=fontsize *6,
739
+ color=fontcolor,
758
740
  bg_color=bg_color,
759
741
  )
760
- img_cmp = cv2.cvtColor(image, cmap)
761
- ax.imshow(image)
742
+ try:
743
+ img_cmp = cv2.cvtColor(image, cmap) if cvt_cmp else image
744
+ except:
745
+ img_cmp = image
746
+
747
+ ax.imshow(img_cmp)
762
748
  ax.axis("off")
763
- # plt.show()
764
- # 根据输出类型返回相应的结果
765
749
  if output == "all":
766
750
  return ax, detections
767
751
  elif "t" in output.lower() and "x" in output.lower():
768
- # 提取文本,过滤低置信度的结果
769
752
  text = [text_ for _, text_, score_ in detections if score_ >= thr]
770
- if postprocess:
771
- return ax, text
772
- else:
773
- return text_corr
753
+ return ax, text
774
754
  elif "score" in output.lower() or "prob" in output.lower():
775
- # 提取分数
776
755
  scores = [score_ for _, _, score_ in detections]
777
756
  return ax, scores
778
757
  elif "box" in output.lower():
779
- # 提取边界框,过滤低置信度的结果
780
758
  bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
781
759
  return ax, bboxes
782
760
  else:
783
- # 默认返回所有检测信息
784
761
  return ax, detections
785
762
  else:
786
- # 根据输出类型返回相应的结果
787
763
  if output == "all":
788
764
  return detections
789
765
  elif "t" in output.lower() and "x" in output.lower():
790
- # 提取文本,过滤低置信度的结果
791
766
  text = [text_ for _, text_, score_ in detections if score_ >= thr]
792
767
  return text
793
768
  elif "score" in output.lower() or "prob" in output.lower():
794
- # 提取分数
795
769
  scores = [score_ for _, _, score_ in detections]
796
770
  return scores
797
771
  elif "box" in output.lower():
798
- # 提取边界框,过滤低置信度的结果
799
772
  bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
800
773
  return bboxes
801
774
  else:
802
- # 默认返回所有检测信息
803
775
  return detections
804
776
  elif "ddddocr" in model.lower():
805
777
  import ddddocr
@@ -844,7 +816,51 @@ def get_text(
844
816
  ax.imshow(image_vis)
845
817
  ax.axis("off")
846
818
  return detections
819
+
820
+ elif "zerox" in model.lower():
821
+ from pyzerox import zerox
822
+ result = zerox(image_process)
823
+ detections = [(bbox, text, score) for bbox, text, score in result]
824
+ # Postprocess and visualize
825
+ if postprocess is None:
826
+ postprocess = dict(
827
+ spell_check=True,
828
+ clean=True,
829
+ filter=dict(min_length=2),
830
+ pattern=None,
831
+ merge=True,
832
+ )
833
+ text_corr = [text_postprocess(text, **postprocess) for _, text, _ in detections]
834
+
835
+ # Display results if 'show' is True
836
+ if show:
837
+ if ax is None:
838
+ ax = plt.gca()
839
+ for bbox, text, score in detections:
840
+ if score > thr:
841
+ top_left = tuple(map(int, bbox[0]))
842
+ bottom_right = tuple(map(int, bbox[2]))
843
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
844
+ image = add_text_pil(image, text, top_left, cvt_cmp=cvt_cmp,font_size=fontsize *6, color=fontcolor, bg_color=bg_color)
845
+ ax.imshow(image)
846
+ ax.axis("off")
847
+
848
+ # Return result based on 'output' type
849
+ if output == "all":
850
+ return ax, detections
851
+ elif "t" in output.lower() and "x" in output.lower():
852
+ text = [text_ for _, text_, score_ in detections if score_ >= thr]
853
+ return ax, text
854
+ elif "score" in output.lower() or "prob" in output.lower():
855
+ scores = [score_ for _, _, score_ in detections]
856
+ return ax, scores
857
+ elif "box" in output.lower():
858
+ bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
859
+ return ax, bboxes
860
+ else:
861
+ return detections
847
862
  else: # "pytesseract"
863
+ import pytesseract
848
864
  if ax is None:
849
865
  ax = plt.gca()
850
866
  text = pytesseract.image_to_string(image_process, lang="+".join(lang), **kwargs)
@@ -869,8 +885,9 @@ def get_text(
869
885
  image,
870
886
  char,
871
887
  left,
872
- font_size=font_scale * 32,
873
- color=font_color,
888
+ cvt_cmp=cvt_cmp,
889
+ font_size=fontsize *6,
890
+ color=fontcolor,
874
891
  )
875
892
  img_cmp = cv2.cvtColor(image, cmap)
876
893
  ax.imshow(img_cmp)
@@ -906,8 +923,8 @@ def draw_box(
906
923
  thr=0.25,
907
924
  cmap=cv2.COLOR_BGR2RGB,
908
925
  box_color=(0, 255, 0), # draw_box
909
- font_color=(0, 0, 255), # draw_box
910
- font_scale=0.8,
926
+ fontcolor=(0, 0, 255), # draw_box
927
+ fontsize=8,
911
928
  show=True,
912
929
  ax=None,
913
930
  **kwargs,
@@ -924,12 +941,9 @@ def draw_box(
924
941
  if score > thr:
925
942
  top_left = tuple(map(int, bbox[0]))
926
943
  bottom_right = tuple(map(int, bbox[2]))
927
- image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
928
- # image = cv2.putText(
929
- # image, text, top_left, font, font_scale, font_color, thickness_text
930
- # )
944
+ image = cv2.rectangle(image, top_left, bottom_right, box_color, 2)
931
945
  image = add_text_pil(
932
- image, text, top_left, font_size=font_scale * 32, color=font_color
946
+ image, text, top_left, cvt_cmp=cvt_cmp,font_size=fontsize *6, color=fontcolor
933
947
  )
934
948
 
935
949
  img_cmp = cv2.cvtColor(image, cmap)