update mobile app for iOS

This commit is contained in:
Maciej Czajka 2023-01-27 01:30:57 +01:00
parent 12340b87e5
commit cfbf50e3eb
12 changed files with 224 additions and 183 deletions

View File

@ -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>

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -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)

View File

@ -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]()

View File

@ -12,3 +12,7 @@ struct LicensePlateItem {
var id = UUID()
var image: Image
}
struct PlatesNumberItem: Codable {
var platesNumber: [String]
}

View File

@ -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)
}
}
}

View File

@ -12,7 +12,7 @@ struct MenuView: View {
TabView {
ContentView()
.tabItem {
Image(systemName: "viewfinder")
Image(systemName: "camera")
Text("Photo")
}
PlatesListView()

View File

@ -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
View File

@ -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__':

View File

@ -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())