update mobile app for iOS
This commit is contained in:
parent
12340b87e5
commit
cfbf50e3eb
Binary file not shown.
@ -3,166 +3,4 @@
|
||||
uuid = "D6BB566A-C242-4B4E-B55F-1FA78A3A061D"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "C405232E-BB0E-451D-8446-9D77C6D5C242"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "44"
|
||||
endingLineNumber = "44"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "964C614A-2A94-484B-995D-37E1EA3A1EE9"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "47"
|
||||
endingLineNumber = "47"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "E81E0E46-48E0-405F-A7FF-B15E52AACF61"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "48"
|
||||
endingLineNumber = "48"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "3F7BADFC-0310-4A3D-ABF6-997289009860"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "52"
|
||||
endingLineNumber = "52"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "DC86FA00-5B66-447C-929B-FD55AF8266F0"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "76"
|
||||
endingLineNumber = "76"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "24FB4CBE-0AAC-4DDA-AEA0-76F900B07C5D"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "45"
|
||||
endingLineNumber = "45"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "7895A366-749C-44A0-80F9-DBE283BC0589"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/ContentView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "169"
|
||||
endingLineNumber = "169"
|
||||
landmarkName = "loadImage()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "2A9DA0ED-54FE-4874-AF3B-2CDDC1E23236"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/ContentView.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "170"
|
||||
endingLineNumber = "170"
|
||||
landmarkName = "loadImage()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "90B92D30-3422-4395-9985-B40318AFD8D8"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Controller/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "62"
|
||||
endingLineNumber = "62"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "8D991345-46AE-480A-9AB9-76AC3F3EC043"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LicensePlates/Controller/Api.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "66"
|
||||
endingLineNumber = "66"
|
||||
landmarkName = "getImageResponse(image:completion:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
21
App/LicensePlates/LicensePlates/Assets.xcassets/plate.imageset/Contents.json
vendored
Normal file
21
App/LicensePlates/LicensePlates/Assets.xcassets/plate.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "plate.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
App/LicensePlates/LicensePlates/Assets.xcassets/plate.imageset/plate.png
vendored
Normal file
BIN
App/LicensePlates/LicensePlates/Assets.xcassets/plate.imageset/plate.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
@ -57,15 +57,75 @@ class Api {
|
||||
|
||||
let myUIImage = responseData.imageFromBase64
|
||||
|
||||
let image = Image(uiImage: myUIImage!)
|
||||
ResponseData.shared.imageData = image
|
||||
PlatesList.shared.imagesList.append(LicensePlateItem(image: image))
|
||||
let new_image = Image(uiImage: myUIImage!)
|
||||
ResponseData.shared.imageData = new_image
|
||||
PlatesList.shared.imagesList.append(LicensePlateItem(image: new_image))
|
||||
|
||||
// using UserDefaults
|
||||
// PlatesList.shared.imagesBase64List.append(myUIImage!.base64!)
|
||||
// UserDefaults.standard.set(PlatesList.shared.imagesBase64List, forKey: "platesList")
|
||||
|
||||
ResponseData.shared.uiImageData = myUIImage!
|
||||
self.getPlatsNumberResponse(image: image) { res in
|
||||
if res == true {
|
||||
completion(true)
|
||||
} else {
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
completion(false)
|
||||
}
|
||||
|
||||
} catch {
|
||||
print("Error: \(error)")
|
||||
completion(false)
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
completion(false)
|
||||
}
|
||||
case.failure:
|
||||
completion(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPlatsNumberResponse(image: String, completion: @escaping(Bool?) -> Void) {
|
||||
let parameters = ["imageFile": image] as [String : Any]
|
||||
|
||||
session.request("http://192.168.5.129:8080/getPlatesNumber", method: .post, parameters: parameters as Parameters, encoding: JSONEncoding.default, headers: nil)
|
||||
.response { response in
|
||||
switch response.result {
|
||||
case.success:
|
||||
if response.response?.statusCode == 200 {
|
||||
let jsonData = response.data
|
||||
do {
|
||||
let allReplies = try JSONDecoder().decode(PlatesNumberItem.self, from: jsonData!)
|
||||
|
||||
if allReplies.platesNumber != ["None"] {
|
||||
// responseData = responseData.replacingOccurrences(of: "b'", with: "")
|
||||
// responseData = String(responseData.replacingOccurrences(of: "\'", with: ""))
|
||||
// responseData = responseData.fixedBase64Format
|
||||
|
||||
for n in allReplies.platesNumber {
|
||||
PlatesList.shared.platesNumberList.append(n)
|
||||
}
|
||||
|
||||
UserDefaults.standard.set(PlatesList.shared.platesNumberList, forKey: "platesList")
|
||||
|
||||
// let myUIImage = responseData.imageFromBase64
|
||||
|
||||
// let image = Image(uiImage: myUIImage!)
|
||||
// ResponseData.shared.imageData = image
|
||||
// PlatesList.shared.imagesList.append(LicensePlateItem(image: image))
|
||||
|
||||
// using UserDefaults
|
||||
// PlatesList.shared.imagesBase64List.append(myUIImage!.base64!)
|
||||
// UserDefaults.standard.set(PlatesList.shared.imagesBase64List, forKey: "platesList")
|
||||
|
||||
// ResponseData.shared.uiImageData = myUIImage!
|
||||
completion(true)
|
||||
} else {
|
||||
completion(false)
|
||||
|
@ -10,6 +10,8 @@ import SwiftUI
|
||||
|
||||
class PlatesList : ObservableObject {
|
||||
@Published var imagesList: [LicensePlateItem] = [LicensePlateItem]()
|
||||
@Published var platesNumberList: [String] = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
|
||||
|
||||
// using UserDefaults
|
||||
// @Published var imagesBase64List: [String] = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
|
||||
|
||||
|
@ -12,3 +12,7 @@ struct LicensePlateItem {
|
||||
var id = UUID()
|
||||
var image: Image
|
||||
}
|
||||
|
||||
struct PlatesNumberItem: Codable {
|
||||
var platesNumber: [String]
|
||||
}
|
||||
|
@ -197,3 +197,23 @@ extension String {
|
||||
return UIImage(data: imageData)
|
||||
}
|
||||
}
|
||||
|
||||
struct ImageOverlay: View {
|
||||
|
||||
var number: String
|
||||
|
||||
init(_ number: String) {
|
||||
self.number = number
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
|
||||
Text(number)
|
||||
.font(.system(size: 50))
|
||||
.font(.callout)
|
||||
.padding(.trailing, 30)
|
||||
.foregroundColor(.black)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ struct MenuView: View {
|
||||
TabView {
|
||||
ContentView()
|
||||
.tabItem {
|
||||
Image(systemName: "viewfinder")
|
||||
Image(systemName: "camera")
|
||||
Text("Photo")
|
||||
}
|
||||
PlatesListView()
|
||||
|
@ -15,21 +15,45 @@ struct PlatesListView: View {
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
VStack {
|
||||
if imagesList.imagesList.isEmpty {
|
||||
if imagesList.platesNumberList.isEmpty {
|
||||
Text("No history")
|
||||
} else {
|
||||
List {
|
||||
ForEach(imagesList.imagesList, id: \.id) { item in
|
||||
item.image
|
||||
ForEach(imagesList.platesNumberList, id: \.self) { item in
|
||||
Image("plate")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.padding()
|
||||
.overlay(ImageOverlay(item), alignment: .trailing)
|
||||
|
||||
// item.image
|
||||
// .resizable()
|
||||
// .scaledToFit()
|
||||
// .padding()
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
isPresented.toggle()
|
||||
} label: {
|
||||
Image(systemName: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $isPresented, content: {
|
||||
Alert(title: Text("Do you want to delete the history?"),
|
||||
primaryButton: .default(Text("No")){
|
||||
},
|
||||
secondaryButton:.default(Text("Yes")) {
|
||||
UserDefaults.standard.set([String](), forKey: "platesList")
|
||||
imagesList.platesNumberList = UserDefaults.standard.stringArray(forKey: "platesList") ?? [String]()
|
||||
})
|
||||
})
|
||||
|
||||
// using UserDefaults
|
||||
// VStack {
|
||||
|
28
api.py
28
api.py
@ -13,6 +13,8 @@ app = Flask(__name__)
|
||||
|
||||
""" Automatic call while FLASK init """
|
||||
|
||||
# def deinit_yolo(yolo):
|
||||
# yolo.close_session()
|
||||
|
||||
"""API_address/ping/<int:id>"""
|
||||
@app.route("/ping/<int:id>", methods=["GET"])
|
||||
@ -27,12 +29,10 @@ def test():
|
||||
o = {'str': 'okokok'}
|
||||
return jsonify(o), 200
|
||||
|
||||
"""API_address/detectLicense?img="""
|
||||
@app.route("/detectLicense", methods=['POST'])
|
||||
def detectLicensePlate():
|
||||
@app.route('/getPlatesNumber', methods=['POST'])
|
||||
def getPlatesNumber():
|
||||
yolo_model = YOLO()
|
||||
res = json.loads(request.data)
|
||||
print('ok')
|
||||
|
||||
# decoded data
|
||||
decoded_data = base64.b64decode(res["imageFile"])
|
||||
@ -40,9 +40,23 @@ def detectLicensePlate():
|
||||
img_file.write(decoded_data)
|
||||
img_file.close()
|
||||
image_path = r'base64.png'
|
||||
base64_b = yolo_video.detect_license_plate(model=yolo_model, img_path=image_path, i=0)
|
||||
print(type(str(base64_b)))
|
||||
res = {'str': str(base64_b)}
|
||||
base64_b, texts = yolo_video.detect_license_plate(model=yolo_model, img_path=image_path, i=0)
|
||||
res = {'platesNumber': texts}
|
||||
return jsonify(res), 200
|
||||
|
||||
"""API_address/detectLicense?img="""
|
||||
@app.route("/detectLicense", methods=['POST'])
|
||||
def detectLicensePlate():
|
||||
yolo_model = YOLO()
|
||||
res = json.loads(request.data)
|
||||
|
||||
# decoded data
|
||||
decoded_data = base64.b64decode(res["imageFile"])
|
||||
img_file = open('base64.png', 'wb')
|
||||
img_file.write(decoded_data)
|
||||
img_file.close()
|
||||
image_path = r'base64.png'
|
||||
base64_b, texts = yolo_video.detect_license_plate(model=yolo_model, img_path=image_path, i=0)
|
||||
return jsonify(str(base64_b)), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -64,20 +64,36 @@ def compute_skew(src_img):
|
||||
def deskew(src_img):
|
||||
return rotate_image(src_img, compute_skew(src_img))
|
||||
|
||||
from keras import backend as K
|
||||
|
||||
|
||||
def detect_img(yolo, img_path, j):
|
||||
try:
|
||||
# processed_image = cv.imread(img_path)
|
||||
# final_image = cv.imread(img_path)
|
||||
# processed_image = cv.resize(processed_image, (3024,3024))
|
||||
# img_path = './img_to_detect.jpeg'
|
||||
# cv.imwrite(img_path, processed_image)
|
||||
image = Image.open(img_path)
|
||||
except:
|
||||
print('Image open Error! Try again!')
|
||||
return None
|
||||
else:
|
||||
# Before prediction
|
||||
# K.clear_session()
|
||||
|
||||
r_image, pred = yolo.detect_image(image)
|
||||
|
||||
# After prediction
|
||||
# K.clear_session()
|
||||
|
||||
r_image.save('detected.png')
|
||||
processed_image = cv.imread(img_path)
|
||||
|
||||
if not pred:
|
||||
return None
|
||||
i = 0
|
||||
texts = []
|
||||
## FIXME : better list mapping
|
||||
for prediction in pred:
|
||||
x1 = prediction[1][0]
|
||||
@ -86,17 +102,36 @@ def detect_img(yolo, img_path, j):
|
||||
y2 = prediction[2][1]
|
||||
w = abs(x1 - x2)
|
||||
h = abs(y1 - y2)
|
||||
# print(pred)
|
||||
# print(f'x1: {x1}, x2: {x2}, y1: {y1}, y2: {y2}, w: {w}, h: {h}')
|
||||
|
||||
img = processed_image[y1:y1 + h, x1:x1 + w]
|
||||
img = deskew(img)
|
||||
|
||||
# gray_image = cv.cvtColor(robot_img, cv.COLOR_BGR2GRAY)
|
||||
# # gray_image = cv.bilateralFilter(gray_image, 11, 17, 17)
|
||||
# gaussian_blur = cv.GaussianBlur(gray_image, (9, 9), 0)
|
||||
# edged = cv.Canny(gaussian_blur, 255, 255)
|
||||
#
|
||||
# image_file = './img0.png'
|
||||
# img = cv.imread(image_file)
|
||||
|
||||
gray_image = grayscale(img)
|
||||
thresh, im_bw = cv.threshold(gray_image, 125, 150, cv.THRESH_BINARY)
|
||||
thresh, im_bw = cv.threshold(gray_image, 125, 150, cv.THRESH_BINARY) #the best = 120,150; 100, 150; 150, 210
|
||||
no_noise = noise_removal(im_bw)
|
||||
no_borders = remove_borders(no_noise)
|
||||
|
||||
# blur = cv.GaussianBlur(gray_image, (3, 3), 0)
|
||||
# thresh = cv.threshold(blur, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1]
|
||||
#
|
||||
# # Morph open to remove noise and invert image
|
||||
# kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
|
||||
# opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=1)
|
||||
# no_borders = 255 - no_borders
|
||||
|
||||
cv.imwrite(f'img/img{j}{i}.png', no_borders)
|
||||
text = ocr.get_text_from_image(f'img/img{j}{i}.png')
|
||||
texts.append(text)
|
||||
if i > 0:
|
||||
processed_image = cv.imread(f'final/final{j}{i-1}.png')
|
||||
res = cv.rectangle(processed_image, (x1, y1), (x1+w, y1+h), (0, 0, 255), 15)
|
||||
@ -104,13 +139,36 @@ def detect_img(yolo, img_path, j):
|
||||
cv.imwrite(f'final/final{j}{i}.png', res)
|
||||
my_string = 'ok'
|
||||
i += 1
|
||||
# with open("final.png", "rb") as img_file:
|
||||
# my_string = base64.b64encode(img_file.read())
|
||||
# print(my_string)
|
||||
with open(f"final/final{j}{i-1}.png", "rb") as img_file:
|
||||
my_string = base64.b64encode(img_file.read())
|
||||
return my_string
|
||||
return my_string, texts
|
||||
|
||||
# text_file = open("base64.txt", "w")
|
||||
# text_file.write(str(my_string))
|
||||
# text_file.close()
|
||||
|
||||
# decoded data
|
||||
# decoded_data = base64.b64decode((my_string))
|
||||
# img_file = open('base64.png', 'wb')
|
||||
# img_file.write(decoded_data)
|
||||
# img_file.close()
|
||||
|
||||
def detect_license_plate(model, img_path, i):
|
||||
str = detect_img(model, img_path, i)
|
||||
if not str:
|
||||
return None
|
||||
str, texts = detect_img(model, img_path, i)
|
||||
if not str or not texts:
|
||||
return None, [None]
|
||||
|
||||
return str
|
||||
return str, texts
|
||||
|
||||
# yolo_model = YOLO()
|
||||
# for i in range(18,100):
|
||||
# image_path = rf'Images/New/IMG_25{i}.jpeg' #95; 3909, 2491
|
||||
# detect_license_plate(model=yolo_model, img_path=image_path, i=i)
|
||||
# image_path = rf'./Images/New/IMG_5016.jpeg' #95; 3909, 2491
|
||||
# detect_license_plate(model=yolo_model, img_path=image_path, i=0)
|
||||
# print(ocr.get_text_from_image(f'img0.png'))
|
||||
# print(ocr.keras_ocr_func())
|
||||
# print(ocr.tesseract_ocr())
|
Loading…
Reference in New Issue
Block a user