Initial commit
|
|
@ -1,6 +1,7 @@
|
|||
venv/
|
||||
venv310/
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.ipynb_checkpoints/
|
||||
*.ipynb
|
||||
temp/
|
||||
|
|
@ -119,10 +119,10 @@ def predict():
|
|||
except Exception as e:
|
||||
|
||||
print("\n❌ ERROR:")
|
||||
print(e)
|
||||
print(str(e))
|
||||
|
||||
return jsonify({
|
||||
"error": "Gagal melakukan prediksi"
|
||||
"error": str(e)
|
||||
}), 500
|
||||
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
import os
|
||||
import numpy as np
|
||||
from tensorflow.keras.preprocessing import image
|
||||
from tensorflow.keras.preprocessing.image import ImageDataGenerator
|
||||
from PIL import Image
|
||||
|
||||
# =========================
|
||||
# PATH GAMBAR ASLI
|
||||
# =========================
|
||||
img_path = r"D:\Corn_Detection\dataset_1150\Hawar\Hawar_0118.jpg"
|
||||
|
||||
# =========================
|
||||
# FOLDER OUTPUT
|
||||
# =========================
|
||||
output_dir = r"D:\Corn_Detection\augmentation"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# =========================
|
||||
# LOAD IMAGE
|
||||
# =========================
|
||||
img = image.load_img(img_path, target_size=(224,224))
|
||||
img_array = image.img_to_array(img)
|
||||
img_array = np.expand_dims(img_array, axis=0)
|
||||
|
||||
# Simpan gambar asli
|
||||
img.save(os.path.join(output_dir, "asli.jpg"))
|
||||
|
||||
# =========================
|
||||
# FUNGSI SIMPAN AUGMENTASI
|
||||
# =========================
|
||||
def save_augmented_image(datagen, filename):
|
||||
aug_iter = datagen.flow(img_array, batch_size=1)
|
||||
|
||||
batch = next(aug_iter)
|
||||
|
||||
img_aug = batch[0].astype("uint8")
|
||||
|
||||
Image.fromarray(img_aug).save(
|
||||
os.path.join(output_dir, filename)
|
||||
)
|
||||
|
||||
# =========================
|
||||
# ROTATION
|
||||
# =========================
|
||||
rotation_gen = ImageDataGenerator(
|
||||
rotation_range=20
|
||||
)
|
||||
|
||||
save_augmented_image(rotation_gen, "rotasi.jpg")
|
||||
|
||||
# =========================
|
||||
# ZOOM
|
||||
# =========================
|
||||
zoom_gen = ImageDataGenerator(
|
||||
zoom_range=0.2
|
||||
)
|
||||
|
||||
save_augmented_image(zoom_gen, "zoom.jpg")
|
||||
|
||||
# =========================
|
||||
# HORIZONTAL FLIP
|
||||
# =========================
|
||||
flip_gen = ImageDataGenerator(
|
||||
horizontal_flip=True
|
||||
)
|
||||
|
||||
save_augmented_image(flip_gen, "horizontal_flip.jpg")
|
||||
|
||||
# =========================
|
||||
# BRIGHTNESS
|
||||
# =========================
|
||||
brightness_gen = ImageDataGenerator(
|
||||
brightness_range=[0.8,1.2]
|
||||
)
|
||||
|
||||
save_augmented_image(brightness_gen, "brightness.jpg")
|
||||
|
||||
# =========================
|
||||
# WIDTH SHIFT
|
||||
# =========================
|
||||
width_shift_gen = ImageDataGenerator(
|
||||
width_shift_range=0.1
|
||||
)
|
||||
|
||||
save_augmented_image(width_shift_gen, "width_shift.jpg")
|
||||
|
||||
# =========================
|
||||
# HEIGHT SHIFT
|
||||
# =========================
|
||||
height_shift_gen = ImageDataGenerator(
|
||||
height_shift_range=0.1
|
||||
)
|
||||
|
||||
save_augmented_image(height_shift_gen, "height_shift.jpg")
|
||||
|
||||
# =========================
|
||||
# SHEAR
|
||||
# =========================
|
||||
shear_gen = ImageDataGenerator(
|
||||
shear_range=0.1
|
||||
)
|
||||
|
||||
save_augmented_image(shear_gen, "shear.jpg")
|
||||
|
||||
print("===================================")
|
||||
print("Semua hasil augmentasi berhasil disimpan")
|
||||
print("Lokasi :", output_dir)
|
||||
print("===================================")
|
||||
|
After Width: | Height: | Size: 52 KiB |
|
|
@ -0,0 +1,8 @@
|
|||
,precision,recall,f1-score,support
|
||||
Bukan Jagung,0.9956521739130435,0.9956521739130435,0.9956521739130435,230.0
|
||||
Hawar,0.9912663755458515,0.9869565217391304,0.9891067538126361,230.0
|
||||
Karat,0.991304347826087,0.991304347826087,0.991304347826087,230.0
|
||||
Sehat,0.9956709956709957,1.0,0.9978308026030369,230.0
|
||||
accuracy,0.9934782608695653,0.9934782608695653,0.9934782608695653,0.9934782608695653
|
||||
macro avg,0.9934734732389945,0.9934782608695653,0.9934735195387009,920.0
|
||||
weighted avg,0.9934734732389945,0.9934782608695653,0.9934735195387009,920.0
|
||||
|
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
|
@ -0,0 +1 @@
|
|||
û¯³‘¯‰Ôƕ㳜÷ÍÚ♫À†Ë‘à—ê<E28094>u ·±™»ÝúÌŠc(¤ŽÜØš©‚Ã×2:&64332632573585195873750373575487188261
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
epoch,accuracy,learning_rate,loss,val_accuracy,val_loss
|
||||
0,0.7136548757553101,9.999999747378752e-05,0.7565154433250427,0.95652174949646,0.19574424624443054
|
||||
1,0.9290081262588501,9.999999747378752e-05,0.23914459347724915,0.976902186870575,0.1129738986492157
|
||||
2,0.9398776888847351,9.999999747378752e-05,0.1800134927034378,0.9755434989929199,0.08709654957056046
|
||||
3,0.9568614363670349,9.999999747378752e-05,0.13939610123634338,0.97826087474823,0.08379809558391571
|
||||
4,0.9616168737411499,9.999999747378752e-05,0.11394604295492172,0.9823369383811951,0.06505417078733444
|
||||
5,0.97044837474823,9.999999747378752e-05,0.09785516560077667,0.9836956262588501,0.058405403047800064
|
||||
6,0.9714673757553101,9.999999747378752e-05,0.0900689959526062,0.9864130616188049,0.05449285730719566
|
||||
7,0.9714673757553101,9.999999747378752e-05,0.08338520675897598,0.98777174949646,0.04825025424361229
|
||||
8,0.981317937374115,9.999999747378752e-05,0.0648878887295723,0.9864130616188049,0.04614263400435448
|
||||
9,0.977921187877655,9.999999747378752e-05,0.06618771702051163,0.9864130616188049,0.043803561478853226
|
||||
10,0.976902186870575,9.999999747378752e-05,0.06501197069883347,0.98777174949646,0.04192778468132019
|
||||
11,0.9786005616188049,9.999999747378752e-05,0.06083962693810463,0.98777174949646,0.043432462960481644
|
||||
12,0.9816576242446899,9.999999747378752e-05,0.0514533556997776,0.98777174949646,0.037732407450675964
|
||||
13,0.9884510636329651,9.999999747378752e-05,0.04559719190001488,0.98777174949646,0.03609374910593033
|
||||
14,0.984714686870575,9.999999747378752e-05,0.046360716223716736,0.99048912525177,0.036957431584596634
|
||||
15,0.9864130616188049,9.999999747378752e-05,0.04609496518969536,0.9850543737411499,0.04189329221844673
|
||||
16,0.9867526888847351,4.999999873689376e-05,0.04231247678399086,0.98777174949646,0.03806684538722038
|
||||
17,0.98607337474823,4.999999873689376e-05,0.040264297276735306,0.98777174949646,0.03658584505319595
|
||||
18,0.98607337474823,2.499999936844688e-05,0.046675294637680054,0.99048912525177,0.03497152402997017
|
||||
19,0.98607337474823,2.499999936844688e-05,0.04432199150323868,0.989130437374115,0.03393092378973961
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
epoch,accuracy,learning_rate,loss,val_accuracy,val_loss
|
||||
0,0.7381114363670349,9.999999747378752e-05,0.7068241834640503,0.9375,0.23247376084327698
|
||||
1,0.930027186870575,9.999999747378752e-05,0.24283264577388763,0.9551630616188049,0.13895472884178162
|
||||
2,0.9429348111152649,9.999999747378752e-05,0.1795891523361206,0.9646739363670349,0.09673672169446945
|
||||
3,0.9609375,9.999999747378752e-05,0.12984155118465424,0.970108687877655,0.08572567254304886
|
||||
4,0.9599184989929199,9.999999747378752e-05,0.11610609292984009,0.97826087474823,0.06869582086801529
|
||||
5,0.963994562625885,9.999999747378752e-05,0.10104407370090485,0.98097825050354,0.05855090171098709
|
||||
6,0.9745244383811951,9.999999747378752e-05,0.0835578665137291,0.9850543737411499,0.05827253311872482
|
||||
7,0.9765625,9.999999747378752e-05,0.0785723403096199,0.9823369383811951,0.05227142199873924
|
||||
8,0.977921187877655,9.999999747378752e-05,0.06692307442426682,0.9823369383811951,0.056870054453611374
|
||||
9,0.981317937374115,9.999999747378752e-05,0.06325101107358932,0.98777174949646,0.0430879108607769
|
||||
10,0.976222813129425,9.999999747378752e-05,0.06722191721200943,0.98777174949646,0.0400400385260582
|
||||
11,0.97826087474823,9.999999747378752e-05,0.056177493184804916,0.99048912525177,0.03674279898405075
|
||||
12,0.98097825050354,9.999999747378752e-05,0.05626058578491211,0.98777174949646,0.039747752249240875
|
||||
13,0.983016312122345,9.999999747378752e-05,0.04855966567993164,0.9932065010070801,0.03457866981625557
|
||||
14,0.984035313129425,9.999999747378752e-05,0.049412332475185394,0.989130437374115,0.03813661262392998
|
||||
15,0.9853940010070801,9.999999747378752e-05,0.04102384299039841,0.989130437374115,0.03746185451745987
|
||||
16,0.987432062625885,4.999999873689376e-05,0.04037996754050255,0.99048912525177,0.03834734484553337
|
||||
17,0.9881114363670349,4.999999873689376e-05,0.04008108749985695,0.991847813129425,0.03469296917319298
|
||||
18,0.98879075050354,2.499999936844688e-05,0.03981376439332962,0.9932065010070801,0.03467719256877899
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
epoch,accuracy,learning_rate,loss,val_accuracy,val_loss
|
||||
0,0.734035313129425,9.999999747378752e-05,0.6999317407608032,0.9442934989929199,0.2147262841463089
|
||||
1,0.9273098111152649,9.999999747378752e-05,0.24060937762260437,0.9646739363670349,0.13419541716575623
|
||||
2,0.94701087474823,9.999999747378752e-05,0.17050962150096893,0.9728260636329651,0.09980986267328262
|
||||
3,0.9572010636329651,9.999999747378752e-05,0.1342485100030899,0.97826087474823,0.07800345122814178
|
||||
4,0.9660326242446899,9.999999747378752e-05,0.10844268649816513,0.98097825050354,0.06890060752630234
|
||||
5,0.9667119383811951,9.999999747378752e-05,0.10096748918294907,0.98097825050354,0.0635373666882515
|
||||
6,0.971807062625885,9.999999747378752e-05,0.0858895480632782,0.9864130616188049,0.05018732696771622
|
||||
7,0.9765625,9.999999747378752e-05,0.07714884728193283,0.9836956262588501,0.05103155970573425
|
||||
8,0.973505437374115,9.999999747378752e-05,0.07740459591150284,0.9823369383811951,0.053474295884370804
|
||||
9,0.9806385636329651,4.999999873689376e-05,0.06630785763263702,0.9864130616188049,0.045486435294151306
|
||||
10,0.9806385636329651,4.999999873689376e-05,0.058046672493219376,0.98777174949646,0.04103342071175575
|
||||
11,0.9823369383811951,4.999999873689376e-05,0.055304937064647675,0.989130437374115,0.041949912905693054
|
||||
12,0.9836956262588501,4.999999873689376e-05,0.05309256166219711,0.989130437374115,0.03986254334449768
|
||||
13,0.9819973111152649,4.999999873689376e-05,0.05787506327033043,0.989130437374115,0.037597913295030594
|
||||
14,0.98267662525177,4.999999873689376e-05,0.05659506097435951,0.991847813129425,0.03598109260201454
|
||||
15,0.983016312122345,4.999999873689376e-05,0.05229465290904045,0.99048912525177,0.03660966083407402
|
||||
16,0.9819973111152649,4.999999873689376e-05,0.05457111448049545,0.99048912525177,0.03671116754412651
|
||||
17,0.98607337474823,2.499999936844688e-05,0.04707670584321022,0.98777174949646,0.03703512251377106
|
||||
18,0.98879075050354,2.499999936844688e-05,0.04428504779934883,0.989130437374115,0.03504762053489685
|
||||
19,0.9867526888847351,2.499999936844688e-05,0.04896799474954605,0.989130437374115,0.03598404303193092
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
epoch,accuracy,learning_rate,loss,val_accuracy,val_loss
|
||||
0,0.748641312122345,9.999999747378752e-05,0.6748814582824707,0.9510869383811951,0.1968584656715393
|
||||
1,0.926630437374115,9.999999747378752e-05,0.23904117941856384,0.9660326242446899,0.12440376728773117
|
||||
2,0.94972825050354,9.999999747378752e-05,0.1546500027179718,0.976902186870575,0.1011323630809784
|
||||
3,0.960597813129425,9.999999747378752e-05,0.13199861347675323,0.9850543737411499,0.07602649927139282
|
||||
4,0.9633151888847351,9.999999747378752e-05,0.11540684849023819,0.9741848111152649,0.07963371276855469
|
||||
5,0.9677309989929199,9.999999747378752e-05,0.09640498459339142,0.9836956262588501,0.059806425124406815
|
||||
6,0.9741848111152649,9.999999747378752e-05,0.08353486657142639,0.98097825050354,0.06453259289264679
|
||||
7,0.9765625,9.999999747378752e-05,0.07739967107772827,0.979619562625885,0.0524170957505703
|
||||
8,0.9786005616188049,9.999999747378752e-05,0.07381828129291534,0.9850543737411499,0.049863629043102264
|
||||
9,0.979619562625885,9.999999747378752e-05,0.06559862196445465,0.9864130616188049,0.04981501027941704
|
||||
10,0.9786005616188049,9.999999747378752e-05,0.06449061632156372,0.98097825050354,0.05683763697743416
|
||||
11,0.98267662525177,4.999999873689376e-05,0.055478502064943314,0.9850543737411499,0.049218062311410904
|
||||
12,0.98267662525177,4.999999873689376e-05,0.05234510824084282,0.9864130616188049,0.04511260613799095
|
||||
13,0.984375,4.999999873689376e-05,0.05012645572423935,0.98777174949646,0.04537223279476166
|
||||
14,0.9850543737411499,4.999999873689376e-05,0.04811901971697807,0.9864130616188049,0.04349565878510475
|
||||
15,0.985733687877655,4.999999873689376e-05,0.04842999577522278,0.9864130616188049,0.040977030992507935
|
||||
16,0.9867526888847351,4.999999873689376e-05,0.047277845442295074,0.9864130616188049,0.039208367466926575
|
||||
17,0.985733687877655,4.999999873689376e-05,0.042227428406476974,0.9864130616188049,0.039824478328228
|
||||
18,0.98777174949646,4.999999873689376e-05,0.039644014090299606,0.9850543737411499,0.03922777995467186
|
||||
19,0.9850543737411499,2.499999936844688e-05,0.04659169539809227,0.9864130616188049,0.041244834661483765
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
epoch,accuracy,learning_rate,loss,val_accuracy,val_loss
|
||||
0,0.7214673757553101,9.999999747378752e-05,0.7529850006103516,0.94701087474823,0.21970611810684204
|
||||
1,0.9191576242446899,9.999999747378752e-05,0.25084418058395386,0.95923912525177,0.12908491492271423
|
||||
2,0.950067937374115,9.999999747378752e-05,0.16257192194461823,0.970108687877655,0.09431818127632141
|
||||
3,0.9582201242446899,9.999999747378752e-05,0.13206881284713745,0.976902186870575,0.07742702215909958
|
||||
4,0.9677309989929199,9.999999747378752e-05,0.10626088827848434,0.9741848111152649,0.06937189400196075
|
||||
5,0.969089686870575,9.999999747378752e-05,0.09285038709640503,0.97826087474823,0.06072676554322243
|
||||
6,0.9667119383811951,9.999999747378752e-05,0.09316759556531906,0.976902186870575,0.05902751162648201
|
||||
7,0.9724864363670349,9.999999747378752e-05,0.07857637107372284,0.97826087474823,0.05389025807380676
|
||||
8,0.976902186870575,9.999999747378752e-05,0.07135744392871857,0.98097825050354,0.05123810097575188
|
||||
9,0.98267662525177,9.999999747378752e-05,0.06045383960008621,0.9823369383811951,0.04801933839917183
|
||||
10,0.97995924949646,9.999999747378752e-05,0.06303825229406357,0.9836956262588501,0.04756370931863785
|
||||
11,0.97826087474823,9.999999747378752e-05,0.06300406157970428,0.9823369383811951,0.04598434641957283
|
||||
12,0.9806385636329651,9.999999747378752e-05,0.05282346531748772,0.9823369383811951,0.0442848727107048
|
||||
13,0.9816576242446899,9.999999747378752e-05,0.05177825316786766,0.9836956262588501,0.044551920145750046
|
||||
14,0.984714686870575,9.999999747378752e-05,0.04417676851153374,0.98097825050354,0.048150435090065
|
||||
15,0.984375,4.999999873689376e-05,0.047107867896556854,0.9850543737411499,0.04266688972711563
|
||||
16,0.9870923757553101,4.999999873689376e-05,0.03834306448698044,0.9850543737411499,0.04022631794214249
|
||||
17,0.9898098111152649,4.999999873689376e-05,0.03330085054039955,0.9850543737411499,0.041328392922878265
|
||||
18,0.9870923757553101,4.999999873689376e-05,0.040723804384469986,0.9850543737411499,0.03947565332055092
|
||||
19,0.9898098111152649,4.999999873689376e-05,0.03469662740826607,0.9836956262588501,0.0406419076025486
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import os
|
||||
from tensorflow.keras.preprocessing import image
|
||||
|
||||
input_path = r"D:\Corn_Detection\dataset_1150\Hawar\Hawar_0118.jpg"
|
||||
|
||||
output_folder = r"D:\Corn_Detection\preprocessing_output\Hawar"
|
||||
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
img = image.load_img(input_path, target_size=(224,224))
|
||||
|
||||
output_path = os.path.join(output_folder, "resize_Hawar_0118.jpg")
|
||||
|
||||
img.save(output_path)
|
||||
|
||||
print("Berhasil disimpan:", output_path)
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
import cv2
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
# =========================
|
||||
# PATH INPUT
|
||||
# =========================
|
||||
img_path = r"D:\Corn_Detection\dataset_1150\Hawar\Hawar_0118.jpg"
|
||||
|
||||
# =========================
|
||||
# PATH OUTPUT
|
||||
# =========================
|
||||
OUTPUT_DIR = r"D:\Corn_Detection\Segmentasi\Hawar"
|
||||
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
# =========================
|
||||
# BACA GAMBAR
|
||||
# =========================
|
||||
img = cv2.imread(img_path)
|
||||
|
||||
if img is None:
|
||||
print("Gambar tidak ditemukan!")
|
||||
exit()
|
||||
|
||||
img_rgb = cv2.cvtColor(
|
||||
img,
|
||||
cv2.COLOR_BGR2RGB
|
||||
)
|
||||
|
||||
# =========================
|
||||
# KONVERSI HSV
|
||||
# =========================
|
||||
hsv = cv2.cvtColor(
|
||||
img,
|
||||
cv2.COLOR_BGR2HSV
|
||||
)
|
||||
|
||||
# =========================
|
||||
# RENTANG WARNA DAUN
|
||||
# =========================
|
||||
lower_green = np.array([15, 20, 20])
|
||||
upper_green = np.array([110, 255, 255])
|
||||
|
||||
mask = cv2.inRange(
|
||||
hsv,
|
||||
lower_green,
|
||||
upper_green
|
||||
)
|
||||
|
||||
# =========================
|
||||
# MORPHOLOGY
|
||||
# =========================
|
||||
kernel = np.ones((7,7), np.uint8)
|
||||
|
||||
mask = cv2.morphologyEx(
|
||||
mask,
|
||||
cv2.MORPH_CLOSE,
|
||||
kernel,
|
||||
iterations=2
|
||||
)
|
||||
|
||||
mask = cv2.dilate(
|
||||
mask,
|
||||
kernel,
|
||||
iterations=2
|
||||
)
|
||||
|
||||
# =========================
|
||||
# CARI KONTUR TERBESAR
|
||||
# =========================
|
||||
contours, _ = cv2.findContours(
|
||||
mask,
|
||||
cv2.RETR_EXTERNAL,
|
||||
cv2.CHAIN_APPROX_SIMPLE
|
||||
)
|
||||
|
||||
if len(contours) == 0:
|
||||
print("Kontur daun tidak ditemukan")
|
||||
exit()
|
||||
|
||||
largest = max(
|
||||
contours,
|
||||
key=cv2.contourArea
|
||||
)
|
||||
|
||||
# =========================
|
||||
# BOUNDING BOX
|
||||
# =========================
|
||||
x, y, w, h = cv2.boundingRect(
|
||||
largest
|
||||
)
|
||||
|
||||
# Tambah margin
|
||||
padding = 20
|
||||
|
||||
x = max(0, x - padding)
|
||||
y = max(0, y - padding)
|
||||
|
||||
w = min(
|
||||
img.shape[1] - x,
|
||||
w + (padding * 2)
|
||||
)
|
||||
|
||||
h = min(
|
||||
img.shape[0] - y,
|
||||
h + (padding * 2)
|
||||
)
|
||||
|
||||
# =========================
|
||||
# CROP DAUN
|
||||
# =========================
|
||||
crop_leaf = img_rgb[
|
||||
y:y+h,
|
||||
x:x+w
|
||||
]
|
||||
|
||||
# =========================
|
||||
# BACKGROUND REMOVAL
|
||||
# =========================
|
||||
background_removed = cv2.bitwise_and(
|
||||
img_rgb,
|
||||
img_rgb,
|
||||
mask=mask
|
||||
)
|
||||
|
||||
# =========================
|
||||
# BOUNDING BOX IMAGE
|
||||
# =========================
|
||||
bbox_img = img_rgb.copy()
|
||||
|
||||
cv2.rectangle(
|
||||
bbox_img,
|
||||
(x, y),
|
||||
(x+w, y+h),
|
||||
(255, 0, 0),
|
||||
3
|
||||
)
|
||||
|
||||
# =========================
|
||||
# MASK BERWARNA
|
||||
# =========================
|
||||
mask_color = cv2.cvtColor(
|
||||
mask,
|
||||
cv2.COLOR_GRAY2BGR
|
||||
)
|
||||
|
||||
# =========================
|
||||
# SIMPAN OUTPUT
|
||||
# =========================
|
||||
cv2.imwrite(
|
||||
os.path.join(
|
||||
OUTPUT_DIR,
|
||||
"0_original.jpg"
|
||||
),
|
||||
img
|
||||
)
|
||||
|
||||
cv2.imwrite(
|
||||
os.path.join(
|
||||
OUTPUT_DIR,
|
||||
"1_mask.jpg"
|
||||
),
|
||||
mask_color
|
||||
)
|
||||
|
||||
cv2.imwrite(
|
||||
os.path.join(
|
||||
OUTPUT_DIR,
|
||||
"2_bounding_box.jpg"
|
||||
),
|
||||
cv2.cvtColor(
|
||||
bbox_img,
|
||||
cv2.COLOR_RGB2BGR
|
||||
)
|
||||
)
|
||||
|
||||
cv2.imwrite(
|
||||
os.path.join(
|
||||
OUTPUT_DIR,
|
||||
"3_crop_leaf.jpg"
|
||||
),
|
||||
cv2.cvtColor(
|
||||
crop_leaf,
|
||||
cv2.COLOR_RGB2BGR
|
||||
)
|
||||
)
|
||||
|
||||
cv2.imwrite(
|
||||
os.path.join(
|
||||
OUTPUT_DIR,
|
||||
"4_background_removed.jpg"
|
||||
),
|
||||
cv2.cvtColor(
|
||||
background_removed,
|
||||
cv2.COLOR_RGB2BGR
|
||||
)
|
||||
)
|
||||
|
||||
print("================================")
|
||||
print("Segmentasi berhasil")
|
||||
print("Output tersimpan di:")
|
||||
print(OUTPUT_DIR)
|
||||
print("================================")
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
# predict.py
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
|
||||
from tensorflow.keras.preprocessing import image
|
||||
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
|
||||
|
||||
# KERAS 3 - LOAD SAVEDMODEL
|
||||
from keras.layers import TFSMLayer
|
||||
|
||||
# ===============================
|
||||
|
|
@ -16,46 +15,58 @@ from keras.layers import TFSMLayer
|
|||
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
|
||||
|
||||
# ===============================
|
||||
# BASE PATH
|
||||
# BASE DIR
|
||||
# ===============================
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
BASE_DIR = os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.abspath(__file__)
|
||||
)
|
||||
)
|
||||
|
||||
# ===============================
|
||||
# PATH MODEL
|
||||
# ===============================
|
||||
MODEL1_PATH = os.path.join(BASE_DIR, "model_model1", "saved_model1")
|
||||
MODEL2_PATH = os.path.join(BASE_DIR, "model_model2", "saved_model2")
|
||||
MODEL_PATH = os.path.join(
|
||||
BASE_DIR,
|
||||
"model",
|
||||
"saved_model"
|
||||
)
|
||||
|
||||
CLASS_PATH = os.path.join(
|
||||
BASE_DIR,
|
||||
"model",
|
||||
"class_names1.pkl"
|
||||
)
|
||||
|
||||
# ===============================
|
||||
# LOAD MODEL
|
||||
# ===============================
|
||||
print("Loading Model 1...")
|
||||
model1 = TFSMLayer(MODEL1_PATH, call_endpoint="serve")
|
||||
print("Loading Model...")
|
||||
|
||||
print("Loading Model 2...")
|
||||
model2 = TFSMLayer(MODEL2_PATH, call_endpoint="serve")
|
||||
model = TFSMLayer(
|
||||
MODEL_PATH,
|
||||
call_endpoint="serve"
|
||||
)
|
||||
|
||||
print("Model berhasil dimuat ✔")
|
||||
print("✅ Model berhasil dimuat")
|
||||
|
||||
# ===============================
|
||||
# LABEL
|
||||
# LOAD CLASS NAMES
|
||||
# ===============================
|
||||
LABELS_MODEL1 = ["jagung", "non_jagung"]
|
||||
with open(CLASS_PATH, "rb") as f:
|
||||
CLASS_NAMES = pickle.load(f)
|
||||
|
||||
LABELS_MODEL2 = [
|
||||
"hawar_daun",
|
||||
"karat_daun",
|
||||
"sehat"
|
||||
]
|
||||
print("Class Names:")
|
||||
print(CLASS_NAMES)
|
||||
|
||||
# ===============================
|
||||
# PREPROCESS IMAGE
|
||||
# ===============================
|
||||
def preprocess_image(img_path, size):
|
||||
def preprocess_image(img_path):
|
||||
|
||||
img = image.load_img(
|
||||
img_path,
|
||||
target_size=size
|
||||
target_size=(224, 224)
|
||||
)
|
||||
|
||||
img_array = image.img_to_array(img)
|
||||
|
|
@ -65,7 +76,9 @@ def preprocess_image(img_path, size):
|
|||
axis=0
|
||||
)
|
||||
|
||||
img_array = preprocess_input(img_array)
|
||||
img_array = preprocess_input(
|
||||
img_array
|
||||
)
|
||||
|
||||
return img_array
|
||||
|
||||
|
|
@ -74,77 +87,42 @@ def preprocess_image(img_path, size):
|
|||
# ===============================
|
||||
def predict_image(image_path):
|
||||
|
||||
# ===========================
|
||||
# CHECK FILE
|
||||
# ===========================
|
||||
if not os.path.exists(image_path):
|
||||
|
||||
raise FileNotFoundError(
|
||||
"File gambar tidak ditemukan"
|
||||
)
|
||||
|
||||
print("\n==============================")
|
||||
print("PREDIKSI GAMBAR")
|
||||
print("==============================")
|
||||
|
||||
# ===========================
|
||||
# MODEL 1
|
||||
# JAGUNG / NON JAGUNG
|
||||
# ===========================
|
||||
img1 = preprocess_image(
|
||||
image_path,
|
||||
(128, 128)
|
||||
img = preprocess_image(
|
||||
image_path
|
||||
)
|
||||
|
||||
preds1 = model1(img1)
|
||||
preds1 = preds1.numpy()[0]
|
||||
preds = model(img)
|
||||
|
||||
idx1 = np.argmax(preds1)
|
||||
preds = preds.numpy()[0]
|
||||
|
||||
label1 = LABELS_MODEL1[idx1]
|
||||
idx = np.argmax(preds)
|
||||
|
||||
conf1 = float(preds1[idx1]) * 100
|
||||
label = CLASS_NAMES[idx]
|
||||
|
||||
print("\n--- MODEL 1 ---")
|
||||
print("Prediksi :", label1)
|
||||
print("Confidence :", f"{conf1:.2f}%")
|
||||
|
||||
# ===========================
|
||||
# JIKA NON JAGUNG
|
||||
# ===========================
|
||||
if label1 == "non_jagung":
|
||||
|
||||
return {
|
||||
"status": "non_jagung",
|
||||
"penyakit": None,
|
||||
"confidence": round(conf1, 2)
|
||||
}
|
||||
|
||||
# ===========================
|
||||
# MODEL 2
|
||||
# PENYAKIT JAGUNG
|
||||
# ===========================
|
||||
img2 = preprocess_image(
|
||||
image_path,
|
||||
(224, 224)
|
||||
)
|
||||
|
||||
preds2 = model2(img2)
|
||||
preds2 = preds2.numpy()[0]
|
||||
|
||||
idx2 = np.argmax(preds2)
|
||||
|
||||
label2 = LABELS_MODEL2[idx2]
|
||||
|
||||
conf2 = float(preds2[idx2]) * 100
|
||||
|
||||
print("\n--- MODEL 2 ---")
|
||||
print("Prediksi :", label2)
|
||||
print("Confidence :", f"{conf2:.2f}%")
|
||||
confidence = float(
|
||||
preds[idx]
|
||||
) * 100
|
||||
|
||||
return {
|
||||
"status": "jagung",
|
||||
"penyakit": label2,
|
||||
"confidence": round(conf2, 2)
|
||||
"kelas": label,
|
||||
"confidence": round(
|
||||
confidence,
|
||||
2
|
||||
),
|
||||
"probabilities": {
|
||||
CLASS_NAMES[i]:
|
||||
round(
|
||||
float(preds[i]) * 100,
|
||||
2
|
||||
)
|
||||
for i in range(len(CLASS_NAMES))
|
||||
}
|
||||
}
|
||||
|
||||
# ===============================
|
||||
|
|
@ -154,13 +132,29 @@ if __name__ == "__main__":
|
|||
|
||||
IMAGE_PATH = os.path.join(
|
||||
BASE_DIR,
|
||||
"test_image5.jpg"
|
||||
"test_image4.jpg"
|
||||
)
|
||||
|
||||
result = predict_image(IMAGE_PATH)
|
||||
result = predict_image(
|
||||
IMAGE_PATH
|
||||
)
|
||||
|
||||
print("\n==============================")
|
||||
print("HASIL AKHIR")
|
||||
print("==============================")
|
||||
print("\n====================")
|
||||
print("HASIL PREDIKSI")
|
||||
print("====================")
|
||||
|
||||
print(result)
|
||||
print(
|
||||
f"Kelas : {result['kelas']}"
|
||||
)
|
||||
|
||||
print(
|
||||
f"Confidence : {result['confidence']}%"
|
||||
)
|
||||
|
||||
print("\nProbabilitas:")
|
||||
|
||||
for k, v in result["probabilities"].items():
|
||||
|
||||
print(
|
||||
f"{k:<15}: {v:.2f}%"
|
||||
)
|
||||
|
|
@ -46,7 +46,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
if (!file) return;
|
||||
|
||||
// Validasi gambar
|
||||
if (!file.type.startsWith("image/")) {
|
||||
alert("File harus berupa gambar!");
|
||||
input.value = "";
|
||||
|
|
@ -55,13 +54,11 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
selectedFile = file;
|
||||
|
||||
// Preview gambar
|
||||
if (previewImage) {
|
||||
previewImage.src = URL.createObjectURL(file);
|
||||
previewImage.style.display = "block";
|
||||
}
|
||||
|
||||
// Reset hasil lama
|
||||
if (resultBox) {
|
||||
resultBox.style.display = "none";
|
||||
}
|
||||
|
|
@ -99,7 +96,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
const formData = new FormData();
|
||||
formData.append("image", selectedFile);
|
||||
|
||||
// Tampilkan loading
|
||||
if (resultBox) {
|
||||
resultBox.style.display = "block";
|
||||
}
|
||||
|
|
@ -121,9 +117,13 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
console.log("Hasil Prediksi:", data);
|
||||
|
||||
// Error backend
|
||||
/**
|
||||
* ==========================================
|
||||
* ERROR BACKEND
|
||||
* ==========================================
|
||||
*/
|
||||
if (!response.ok) {
|
||||
|
||||
if (diseaseName) {
|
||||
|
|
@ -140,49 +140,39 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
/**
|
||||
* ==========================================
|
||||
* HASIL NON JAGUNG
|
||||
* HASIL PREDIKSI
|
||||
* ==========================================
|
||||
*/
|
||||
if (data.status === "non_jagung") {
|
||||
let kelas = data.kelas;
|
||||
|
||||
if (diseaseName) {
|
||||
diseaseName.textContent =
|
||||
"❌ Gambar bukan daun jagung";
|
||||
}
|
||||
|
||||
if (confidenceText) {
|
||||
confidenceText.textContent =
|
||||
`Tingkat Kepercayaan: ${data.confidence}%`;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* ==========================================
|
||||
* HASIL JAGUNG
|
||||
* ==========================================
|
||||
*/
|
||||
if (diseaseName) {
|
||||
|
||||
let penyakit = data.penyakit;
|
||||
|
||||
// Format nama penyakit
|
||||
if (penyakit === "hawar_daun") {
|
||||
penyakit = "Hawar Daun";
|
||||
}
|
||||
else if (penyakit === "karat_daun") {
|
||||
penyakit = "Karat Daun";
|
||||
}
|
||||
else if (penyakit === "sehat") {
|
||||
penyakit = "Daun Sehat";
|
||||
}
|
||||
if (kelas === "Bukan Jagung") {
|
||||
|
||||
diseaseName.textContent =
|
||||
`🌽 Penyakit: ${penyakit}`;
|
||||
"❌ Gambar Bukan Daun Jagung";
|
||||
|
||||
} else if (kelas === "Hawar") {
|
||||
|
||||
diseaseName.textContent =
|
||||
"🌽 Penyakit: Hawar Daun";
|
||||
|
||||
} else if (kelas === "Karat") {
|
||||
|
||||
diseaseName.textContent =
|
||||
"🌽 Penyakit: Karat Daun";
|
||||
|
||||
} else if (kelas === "Sehat") {
|
||||
|
||||
diseaseName.textContent =
|
||||
"🌿 Daun Jagung Sehat";
|
||||
|
||||
} else {
|
||||
|
||||
diseaseName.textContent =
|
||||
`🌽 Hasil Deteksi: ${kelas}`;
|
||||
}
|
||||
|
||||
if (confidenceText) {
|
||||
|
||||
confidenceText.textContent =
|
||||
`Tingkat Kepercayaan: ${data.confidence}%`;
|
||||
}
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |