New Hope. Adding photos and search by number
@ -120,3 +120,5 @@ USE_TZ = True
|
|||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "bibrecognition/images")
|
||||||
|
MEDIA_URL = '/images/'
|
||||||
|
BIN
bibrecognition/images/bib_01.jpg
Normal file
After Width: | Height: | Size: 456 KiB |
BIN
bibrecognition/images/bib_01_GBMDqei.jpg
Normal file
After Width: | Height: | Size: 456 KiB |
BIN
bibrecognition/images/bib_01_L2ZLOit.jpg
Normal file
After Width: | Height: | Size: 456 KiB |
BIN
bibrecognition/images/bib_01_SMItOxE.jpg
Normal file
After Width: | Height: | Size: 456 KiB |
BIN
bibrecognition/images/bib_03.jpg
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
bibrecognition/images/bib_03_nr7BMDD.jpg
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
bibrecognition/images/bib_04.jpg
Normal file
After Width: | Height: | Size: 528 KiB |
@ -7,3 +7,9 @@ class PhotoForm(forms.Form):
|
|||||||
queryset=Competitions.objects.all(), to_field_name="comp_slug")
|
queryset=Competitions.objects.all(), to_field_name="comp_slug")
|
||||||
file_field = forms.FileField(
|
file_field = forms.FileField(
|
||||||
widget=forms.ClearableFileInput(attrs={'multiple': True}))
|
widget=forms.ClearableFileInput(attrs={'multiple': True}))
|
||||||
|
|
||||||
|
|
||||||
|
class SearchForm(forms.Form):
|
||||||
|
zawody = forms.ModelChoiceField(
|
||||||
|
queryset=Competitions.objects.all(), to_field_name="comp_slug")
|
||||||
|
numer = forms.DecimalField(decimal_places=0)
|
||||||
|
@ -37,7 +37,7 @@ def decode_predictions(scores, geometry):
|
|||||||
for x in range(0, numCols):
|
for x in range(0, numCols):
|
||||||
# if our score does not have sufficient probability,
|
# if our score does not have sufficient probability,
|
||||||
# ignore it
|
# ignore it
|
||||||
if scoresData[x] < args["min_confidence"]:
|
if scoresData[x] < 0.5:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# compute the offset factor as our resulting feature
|
# compute the offset factor as our resulting feature
|
||||||
@ -71,123 +71,65 @@ def decode_predictions(scores, geometry):
|
|||||||
return (rects, confidences)
|
return (rects, confidences)
|
||||||
|
|
||||||
|
|
||||||
def findNumber():
|
def findNumber(url):
|
||||||
|
image = cv2.imread(url)
|
||||||
|
orig = image.copy()
|
||||||
|
(origH, origW) = image.shape[:2]
|
||||||
|
(newW, newH) = (320,320)
|
||||||
|
rW = origW / float(newW)
|
||||||
|
rH = origH / float(newH)
|
||||||
|
image = cv2.resize(image, (newW, newH))
|
||||||
|
(H, W) = image.shape[:2]
|
||||||
|
layerNames = [
|
||||||
|
"feature_fusion/Conv_7/Sigmoid",
|
||||||
|
"feature_fusion/concat_3"]
|
||||||
|
net = cv2.dnn.readNet("../EAST/frozen_east_text_detection.pb")
|
||||||
|
blob = cv2.dnn.blobFromImage(image, 1.0, (W, H),
|
||||||
|
(123.68, 116.78, 103.94), swapRB=True, crop=False)
|
||||||
|
net.setInput(blob)
|
||||||
|
(scores, geometry) = net.forward(layerNames)
|
||||||
|
(rects, confidences) = decode_predictions(scores, geometry)
|
||||||
|
boxes = non_max_suppression(np.array(rects), probs=confidences)
|
||||||
|
results = []
|
||||||
|
for (startX, startY, endX, endY) in boxes:
|
||||||
|
|
||||||
|
startX = int(startX * rW)
|
||||||
|
startY = int(startY * rH)
|
||||||
|
endX = int(endX * rW)
|
||||||
|
endY = int(endY * rH)
|
||||||
|
|
||||||
|
dX = int((endX - startX) * 0.0)
|
||||||
|
dY = int((endY - startY) * 0.0)
|
||||||
|
|
||||||
|
startX = max(0, startX - dX)
|
||||||
|
startY = max(0, startY - dY)
|
||||||
|
endX = min(origW, endX + (dX * 2))
|
||||||
|
endY = min(origH, endY + (dY * 2))
|
||||||
|
|
||||||
|
roi = orig[startY:endY, startX:endX]
|
||||||
|
|
||||||
|
config = ("-l eng --oem 1 --psm 7")
|
||||||
|
text = pytesseract.image_to_string(roi, config=config)
|
||||||
|
|
||||||
|
results.append(((startX, startY, endX, endY), text))
|
||||||
|
|
||||||
|
results = sorted(results, key=lambda r: r[0][1])
|
||||||
|
wyniki = []
|
||||||
|
for ((startX, startY, endX, endY), text) in results:
|
||||||
|
if( text.isdigit() ):
|
||||||
|
wyniki.append(text)
|
||||||
|
# print("OCR TEXT")
|
||||||
|
# print("========")
|
||||||
|
# print("{}\n".format(text))
|
||||||
|
|
||||||
|
# text = "".join([c if ord(c) < 128 else "" for c in text]).strip()
|
||||||
|
# output = orig.copy()
|
||||||
|
# cv2.rectangle(output, (startX, startY), (endX, endY),
|
||||||
|
# (0, 0, 255), 2)
|
||||||
|
# cv2.putText(output, text, (startX, startY - 20),
|
||||||
|
# cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3)
|
||||||
|
|
||||||
|
# cv2.imshow("Text Detection", output)
|
||||||
|
# cv2.waitKey(0)
|
||||||
|
|
||||||
return 0
|
return wyniki
|
||||||
|
|
||||||
# construct the argument parser and parse the arguments
|
|
||||||
ap = argparse.ArgumentParser()
|
|
||||||
ap.add_argument("-i", "--image", type=str,
|
|
||||||
help="path to input image")
|
|
||||||
ap.add_argument("-east", "--east", type=str, default="./EAST/frozen_east_text_detection.pb",
|
|
||||||
help="path to input EAST text detector")
|
|
||||||
ap.add_argument("-c", "--min-confidence", type=float, default=0.5,
|
|
||||||
help="minimum probability required to inspect a region")
|
|
||||||
ap.add_argument("-w", "--width", type=int, default=320,
|
|
||||||
help="nearest multiple of 32 for resized width")
|
|
||||||
ap.add_argument("-e", "--height", type=int, default=320,
|
|
||||||
help="nearest multiple of 32 for resized height")
|
|
||||||
ap.add_argument("-p", "--padding", type=float, default=0.0,
|
|
||||||
help="amount of padding to add to each border of ROI")
|
|
||||||
args = vars(ap.parse_args())
|
|
||||||
|
|
||||||
# load the input image and grab the image dimensions
|
|
||||||
image = cv2.imread(args["image"])
|
|
||||||
orig = image.copy()
|
|
||||||
(origH, origW) = image.shape[:2]
|
|
||||||
|
|
||||||
# set the new width and height and then determine the ratio in change
|
|
||||||
# for both the width and height
|
|
||||||
(newW, newH) = (args["width"], args["height"])
|
|
||||||
rW = origW / float(newW)
|
|
||||||
rH = origH / float(newH)
|
|
||||||
|
|
||||||
# resize the image and grab the new image dimensions
|
|
||||||
image = cv2.resize(image, (newW, newH))
|
|
||||||
(H, W) = image.shape[:2]
|
|
||||||
|
|
||||||
# define the two output layer names for the EAST detector model that
|
|
||||||
# we are interested -- the first is the output probabilities and the
|
|
||||||
# second can be used to derive the bounding box coordinates of text
|
|
||||||
layerNames = [
|
|
||||||
"feature_fusion/Conv_7/Sigmoid",
|
|
||||||
"feature_fusion/concat_3"]
|
|
||||||
|
|
||||||
# load the pre-trained EAST text detector
|
|
||||||
print("[INFO] loading EAST text detector...")
|
|
||||||
net = cv2.dnn.readNet(args["east"])
|
|
||||||
|
|
||||||
# construct a blob from the image and then perform a forward pass of
|
|
||||||
# the model to obtain the two output layer sets
|
|
||||||
blob = cv2.dnn.blobFromImage(image, 1.0, (W, H),
|
|
||||||
(123.68, 116.78, 103.94), swapRB=True, crop=False)
|
|
||||||
net.setInput(blob)
|
|
||||||
(scores, geometry) = net.forward(layerNames)
|
|
||||||
|
|
||||||
# decode the predictions, then apply non-maxima suppression to
|
|
||||||
# suppress weak, overlapping bounding boxes
|
|
||||||
(rects, confidences) = decode_predictions(scores, geometry)
|
|
||||||
boxes = non_max_suppression(np.array(rects), probs=confidences)
|
|
||||||
|
|
||||||
# initialize the list of results
|
|
||||||
results = []
|
|
||||||
|
|
||||||
# loop over the bounding boxes
|
|
||||||
for (startX, startY, endX, endY) in boxes:
|
|
||||||
# scale the bounding box coordinates based on the respective
|
|
||||||
# ratios
|
|
||||||
startX = int(startX * rW)
|
|
||||||
startY = int(startY * rH)
|
|
||||||
endX = int(endX * rW)
|
|
||||||
endY = int(endY * rH)
|
|
||||||
|
|
||||||
# in order to obtain a better OCR of the text we can potentially
|
|
||||||
# apply a bit of padding surrounding the bounding box -- here we
|
|
||||||
# are computing the deltas in both the x and y directions
|
|
||||||
dX = int((endX - startX) * args["padding"])
|
|
||||||
dY = int((endY - startY) * args["padding"])
|
|
||||||
|
|
||||||
# apply padding to each side of the bounding box, respectively
|
|
||||||
startX = max(0, startX - dX)
|
|
||||||
startY = max(0, startY - dY)
|
|
||||||
endX = min(origW, endX + (dX * 2))
|
|
||||||
endY = min(origH, endY + (dY * 2))
|
|
||||||
|
|
||||||
# extract the actual padded ROI
|
|
||||||
roi = orig[startY:endY, startX:endX]
|
|
||||||
|
|
||||||
# in order to apply Tesseract v4 to OCR text we must supply
|
|
||||||
# (1) a language, (2) an OEM flag of 4, indicating that the we
|
|
||||||
# wish to use the LSTM neural net model for OCR, and finally
|
|
||||||
# (3) an OEM value, in this case, 7 which implies that we are
|
|
||||||
# treating the ROI as a single line of text
|
|
||||||
config = ("-l eng --oem 1 --psm 7")
|
|
||||||
text = pytesseract.image_to_string(roi, config=config)
|
|
||||||
|
|
||||||
# add the bounding box coordinates and OCR'd text to the list
|
|
||||||
# of results
|
|
||||||
results.append(((startX, startY, endX, endY), text))
|
|
||||||
|
|
||||||
# sort the results bounding box coordinates from top to bottom
|
|
||||||
results = sorted(results, key=lambda r: r[0][1])
|
|
||||||
|
|
||||||
# loop over the results
|
|
||||||
for ((startX, startY, endX, endY), text) in results:
|
|
||||||
# display the text OCR'd by Tesseract
|
|
||||||
print("OCR TEXT")
|
|
||||||
print("========")
|
|
||||||
print("{}\n".format(text))
|
|
||||||
|
|
||||||
# strip out non-ASCII text so we can draw the text on the image
|
|
||||||
# using OpenCV, then draw the text and a bounding box surrounding
|
|
||||||
# the text region of the input image
|
|
||||||
text = "".join([c if ord(c) < 128 else "" for c in text]).strip()
|
|
||||||
output = orig.copy()
|
|
||||||
cv2.rectangle(output, (startX, startY), (endX, endY),
|
|
||||||
(0, 0, 255), 2)
|
|
||||||
cv2.putText(output, text, (startX, startY - 20),
|
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3)
|
|
||||||
|
|
||||||
# show the output image
|
|
||||||
cv2.imshow("Text Detection", output)
|
|
||||||
cv2.waitKey(0)
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 3.0.3 on 2020-06-19 23:49
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('imguploader', '0003_competitions_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='photo',
|
||||||
|
name='url',
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 3.0.3 on 2020-06-20 00:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('imguploader', '0004_remove_photo_url'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='photometa',
|
||||||
|
name='comp_id',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='imguploader.Competitions'),
|
||||||
|
),
|
||||||
|
]
|
@ -1,8 +1,8 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class PhotoManager(models.Manager):
|
class PhotoManager(models.Manager):
|
||||||
def create_photo(self, comp_id, name, image, url):
|
def create_photo(self, comp_id, name, image):
|
||||||
photo = self.create(comp_id = comp_id, name = name, image = image, url = url)
|
photo = self.create(comp_id = comp_id, name = name, image = image)
|
||||||
|
|
||||||
return photo
|
return photo
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
@ -18,10 +18,15 @@ class Photo(models.Model):
|
|||||||
comp_id = models.ForeignKey(Competitions, on_delete=models.CASCADE)
|
comp_id = models.ForeignKey(Competitions, on_delete=models.CASCADE)
|
||||||
name = models.CharField(max_length=100, default='Zdjecie')
|
name = models.CharField(max_length=100, default='Zdjecie')
|
||||||
image = models.ImageField(upload_to='images/', default='placeholder.jpg')
|
image = models.ImageField(upload_to='images/', default='placeholder.jpg')
|
||||||
url = models.CharField(max_length=50)
|
# url = models.CharField(max_length=50)
|
||||||
objects = PhotoManager()
|
objects = PhotoManager()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class PhotoMeta(models.Model):
|
class PhotoMeta(models.Model):
|
||||||
|
comp_id = models.ForeignKey(Competitions, on_delete=models.CASCADE, null=True)
|
||||||
photo_id = models.ForeignKey(Photo, on_delete=models.CASCADE)
|
photo_id = models.ForeignKey(Photo, on_delete=models.CASCADE)
|
||||||
meta_key = models.CharField(max_length=50)
|
meta_key = models.CharField(max_length=50)
|
||||||
meta_value = models.CharField(max_length=50)
|
meta_value = models.CharField(max_length=50)
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
Zalogowany 😎
|
Zalogowany 😎 <br />
|
||||||
|
<a href="{% url 'upload' %}">Załaduj zdjęcia</a><br />
|
||||||
|
<a href="{% url 'search' %}">Przeszukaj bazę</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
Gość 🏃♀️
|
Gość 🏃♀️<br />
|
||||||
|
<a href="{% url 'search' %}">Przeszukaj bazę</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
27
bibrecognition/imguploader/templates/search.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Search Photos</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
{% if form %}
|
||||||
|
<form action="/search" method="post" >
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if foto %}
|
||||||
|
<ul>
|
||||||
|
{% for n in foto %}
|
||||||
|
<li><img src="{{ n }}" /></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -1,8 +1,16 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name="index"),
|
path('', views.index, name="index"),
|
||||||
path('upload', views.uploadPhotos, name="upload"),
|
path('upload', views.uploadPhotos, name="upload"),
|
||||||
|
path('search', views.searchPhotos, name="search"),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from .forms import PhotoForm
|
from .forms import PhotoForm
|
||||||
|
from .forms import SearchForm
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
|
||||||
from .models import PhotoManager
|
from .models import PhotoManager
|
||||||
from .models import Photo
|
from .models import Photo
|
||||||
from .models import Competitions
|
from .models import Competitions
|
||||||
|
from .models import PhotoMeta
|
||||||
|
|
||||||
# from .functions import test
|
from .functions import findNumber
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
@ -25,15 +27,61 @@ def uploadPhotos(request):
|
|||||||
for f in files:
|
for f in files:
|
||||||
zawody = Competitions.objects.get(comp_slug=comp)
|
zawody = Competitions.objects.get(comp_slug=comp)
|
||||||
|
|
||||||
photo = Photo.objects.create_photo(zawody,f,f,'test')
|
# photo = Photo.objects.create_photo(zawody,comp+"_"+f,f)
|
||||||
|
file_name = comp+"_"+f.name
|
||||||
|
photo = Photo(comp_id=zawody, name=file_name, image=f)
|
||||||
|
photo.save(force_insert=True)
|
||||||
|
# print("URL of photo: "+photo.image.url)
|
||||||
|
numbers = findNumber(photo.image.url)
|
||||||
|
|
||||||
|
for nr in numbers:
|
||||||
|
pm = PhotoMeta(comp_id=zawody, photo_id=photo, meta_key="detect_number", meta_value=nr)
|
||||||
|
pm.save(force_insert=True)
|
||||||
# return self.form_valid(form)
|
# return self.form_valid(form)
|
||||||
return HttpResponseRedirect('/success/url/')
|
return HttpResponseRedirect('/success/')
|
||||||
else:
|
else:
|
||||||
# return self.form_invalid(form)
|
# return self.form_invalid(form)
|
||||||
# form.save()
|
# form.save()
|
||||||
# return render(request, print(request.FILES['file_field']))
|
# return render(request, print(request.FILES['file_field']))
|
||||||
return HttpResponseRedirect('/faild/url/')
|
return HttpResponseRedirect('/failed/')
|
||||||
else:
|
else:
|
||||||
form = PhotoForm()
|
form = PhotoForm()
|
||||||
return render(request, 'upload.html', {'form': form})
|
return render(request, 'upload.html', {'form': form})
|
||||||
# return HttpResponse("Hello, world. This is imageUploader")
|
# return HttpResponse("Hello, world. This is imageUploader")
|
||||||
|
|
||||||
|
|
||||||
|
def searchPhotos(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = SearchForm(request.POST)
|
||||||
|
comp = request.POST['zawody']
|
||||||
|
numer = request.POST['numer']
|
||||||
|
print(request)
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
allFotos = []
|
||||||
|
imgUrls = []
|
||||||
|
zawody = Competitions.objects.get(comp_slug=comp)
|
||||||
|
try:
|
||||||
|
zdjecia = PhotoMeta.objects.filter(comp_id=zawody, meta_value=numer)
|
||||||
|
except PhotoMeta.DoesNotExist:
|
||||||
|
zdjecia = None
|
||||||
|
if( zdjecia ):
|
||||||
|
for zdjecie in zdjecia:
|
||||||
|
# allFotos.append(Photo.objects.get(id=zdjecie.photo_id))
|
||||||
|
imgUrls.append(zdjecie.photo_id.image.name)
|
||||||
|
|
||||||
|
# for fotos in allFotos:
|
||||||
|
# imgUrls.append(fotos.image.url)
|
||||||
|
|
||||||
|
return render(request, 'search.html', {'foto': imgUrls})
|
||||||
|
else:
|
||||||
|
print('no ni ma')
|
||||||
|
|
||||||
|
return HttpResponseRedirect('/success/')
|
||||||
|
else:
|
||||||
|
|
||||||
|
return HttpResponseRedirect('/failed/')
|
||||||
|
else:
|
||||||
|
form = SearchForm()
|
||||||
|
return render(request, 'search.html', {'form': form})
|
||||||
|
# return HttpResponse("Hello, world. This is imageUploader")
|
||||||
|
BIN
imgs/bib_03_bw.jpg
Normal file
After Width: | Height: | Size: 261 KiB |
BIN
imgs/bib_04.jpg
Normal file
After Width: | Height: | Size: 528 KiB |
3
main.py
@ -169,12 +169,14 @@ for (startX, startY, endX, endY) in boxes:
|
|||||||
results = sorted(results, key=lambda r: r[0][1])
|
results = sorted(results, key=lambda r: r[0][1])
|
||||||
|
|
||||||
# loop over the results
|
# loop over the results
|
||||||
|
|
||||||
for ((startX, startY, endX, endY), text) in results:
|
for ((startX, startY, endX, endY), text) in results:
|
||||||
# display the text OCR'd by Tesseract
|
# display the text OCR'd by Tesseract
|
||||||
print("OCR TEXT")
|
print("OCR TEXT")
|
||||||
print("========")
|
print("========")
|
||||||
print("{}\n".format(text))
|
print("{}\n".format(text))
|
||||||
|
|
||||||
|
|
||||||
# strip out non-ASCII text so we can draw the text on the image
|
# strip out non-ASCII text so we can draw the text on the image
|
||||||
# using OpenCV, then draw the text and a bounding box surrounding
|
# using OpenCV, then draw the text and a bounding box surrounding
|
||||||
# the text region of the input image
|
# the text region of the input image
|
||||||
@ -188,3 +190,4 @@ for ((startX, startY, endX, endY), text) in results:
|
|||||||
# show the output image
|
# show the output image
|
||||||
cv2.imshow("Text Detection", output)
|
cv2.imshow("Text Detection", output)
|
||||||
cv2.waitKey(0)
|
cv2.waitKey(0)
|
||||||
|
|
||||||
|