Initial commit

This commit is contained in:
Tariskadebby 2026-07-07 12:30:08 +07:00
parent cdc09228cd
commit 4414b1bad0
9229 changed files with 556 additions and 130 deletions

View File

@ -1,6 +1,7 @@
venv/
venv310/
.venv/
__pycache__/
*.pyc
.ipynb_checkpoints/
*.ipynb
*.ipynb
temp/

View File

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

108
backend/augmentasi.py Normal file
View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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
1 precision recall f1-score support
2 Bukan Jagung 0.9956521739130435 0.9956521739130435 0.9956521739130435 230.0
3 Hawar 0.9912663755458515 0.9869565217391304 0.9891067538126361 230.0
4 Karat 0.991304347826087 0.991304347826087 0.991304347826087 230.0
5 Sehat 0.9956709956709957 1.0 0.9978308026030369 230.0
6 accuracy 0.9934782608695653 0.9934782608695653 0.9934782608695653 0.9934782608695653
7 macro avg 0.9934734732389945 0.9934782608695653 0.9934735195387009 920.0
8 weighted avg 0.9934734732389945 0.9934782608695653 0.9934735195387009 920.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
backend/model/model_best.h5 Normal file

Binary file not shown.

Binary file not shown.

BIN
backend/model/roc_curve.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View File

@ -0,0 +1 @@
û¯³‘¯‰ÔÆ•㳜÷ÍÚ♫À†Ëà—ê<E28094>u ·±™»ÝúÌŠc(¤ŽÜØš©‚Ã×2:&64332632573585195873750373575487188261

Binary file not shown.

Binary file not shown.

View File

@ -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
1 epoch accuracy learning_rate loss val_accuracy val_loss
2 0 0.7136548757553101 9.999999747378752e-05 0.7565154433250427 0.95652174949646 0.19574424624443054
3 1 0.9290081262588501 9.999999747378752e-05 0.23914459347724915 0.976902186870575 0.1129738986492157
4 2 0.9398776888847351 9.999999747378752e-05 0.1800134927034378 0.9755434989929199 0.08709654957056046
5 3 0.9568614363670349 9.999999747378752e-05 0.13939610123634338 0.97826087474823 0.08379809558391571
6 4 0.9616168737411499 9.999999747378752e-05 0.11394604295492172 0.9823369383811951 0.06505417078733444
7 5 0.97044837474823 9.999999747378752e-05 0.09785516560077667 0.9836956262588501 0.058405403047800064
8 6 0.9714673757553101 9.999999747378752e-05 0.0900689959526062 0.9864130616188049 0.05449285730719566
9 7 0.9714673757553101 9.999999747378752e-05 0.08338520675897598 0.98777174949646 0.04825025424361229
10 8 0.981317937374115 9.999999747378752e-05 0.0648878887295723 0.9864130616188049 0.04614263400435448
11 9 0.977921187877655 9.999999747378752e-05 0.06618771702051163 0.9864130616188049 0.043803561478853226
12 10 0.976902186870575 9.999999747378752e-05 0.06501197069883347 0.98777174949646 0.04192778468132019
13 11 0.9786005616188049 9.999999747378752e-05 0.06083962693810463 0.98777174949646 0.043432462960481644
14 12 0.9816576242446899 9.999999747378752e-05 0.0514533556997776 0.98777174949646 0.037732407450675964
15 13 0.9884510636329651 9.999999747378752e-05 0.04559719190001488 0.98777174949646 0.03609374910593033
16 14 0.984714686870575 9.999999747378752e-05 0.046360716223716736 0.99048912525177 0.036957431584596634
17 15 0.9864130616188049 9.999999747378752e-05 0.04609496518969536 0.9850543737411499 0.04189329221844673
18 16 0.9867526888847351 4.999999873689376e-05 0.04231247678399086 0.98777174949646 0.03806684538722038
19 17 0.98607337474823 4.999999873689376e-05 0.040264297276735306 0.98777174949646 0.03658584505319595
20 18 0.98607337474823 2.499999936844688e-05 0.046675294637680054 0.99048912525177 0.03497152402997017
21 19 0.98607337474823 2.499999936844688e-05 0.04432199150323868 0.989130437374115 0.03393092378973961

View File

@ -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
1 epoch accuracy learning_rate loss val_accuracy val_loss
2 0 0.7381114363670349 9.999999747378752e-05 0.7068241834640503 0.9375 0.23247376084327698
3 1 0.930027186870575 9.999999747378752e-05 0.24283264577388763 0.9551630616188049 0.13895472884178162
4 2 0.9429348111152649 9.999999747378752e-05 0.1795891523361206 0.9646739363670349 0.09673672169446945
5 3 0.9609375 9.999999747378752e-05 0.12984155118465424 0.970108687877655 0.08572567254304886
6 4 0.9599184989929199 9.999999747378752e-05 0.11610609292984009 0.97826087474823 0.06869582086801529
7 5 0.963994562625885 9.999999747378752e-05 0.10104407370090485 0.98097825050354 0.05855090171098709
8 6 0.9745244383811951 9.999999747378752e-05 0.0835578665137291 0.9850543737411499 0.05827253311872482
9 7 0.9765625 9.999999747378752e-05 0.0785723403096199 0.9823369383811951 0.05227142199873924
10 8 0.977921187877655 9.999999747378752e-05 0.06692307442426682 0.9823369383811951 0.056870054453611374
11 9 0.981317937374115 9.999999747378752e-05 0.06325101107358932 0.98777174949646 0.0430879108607769
12 10 0.976222813129425 9.999999747378752e-05 0.06722191721200943 0.98777174949646 0.0400400385260582
13 11 0.97826087474823 9.999999747378752e-05 0.056177493184804916 0.99048912525177 0.03674279898405075
14 12 0.98097825050354 9.999999747378752e-05 0.05626058578491211 0.98777174949646 0.039747752249240875
15 13 0.983016312122345 9.999999747378752e-05 0.04855966567993164 0.9932065010070801 0.03457866981625557
16 14 0.984035313129425 9.999999747378752e-05 0.049412332475185394 0.989130437374115 0.03813661262392998
17 15 0.9853940010070801 9.999999747378752e-05 0.04102384299039841 0.989130437374115 0.03746185451745987
18 16 0.987432062625885 4.999999873689376e-05 0.04037996754050255 0.99048912525177 0.03834734484553337
19 17 0.9881114363670349 4.999999873689376e-05 0.04008108749985695 0.991847813129425 0.03469296917319298
20 18 0.98879075050354 2.499999936844688e-05 0.03981376439332962 0.9932065010070801 0.03467719256877899

View File

@ -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
1 epoch accuracy learning_rate loss val_accuracy val_loss
2 0 0.734035313129425 9.999999747378752e-05 0.6999317407608032 0.9442934989929199 0.2147262841463089
3 1 0.9273098111152649 9.999999747378752e-05 0.24060937762260437 0.9646739363670349 0.13419541716575623
4 2 0.94701087474823 9.999999747378752e-05 0.17050962150096893 0.9728260636329651 0.09980986267328262
5 3 0.9572010636329651 9.999999747378752e-05 0.1342485100030899 0.97826087474823 0.07800345122814178
6 4 0.9660326242446899 9.999999747378752e-05 0.10844268649816513 0.98097825050354 0.06890060752630234
7 5 0.9667119383811951 9.999999747378752e-05 0.10096748918294907 0.98097825050354 0.0635373666882515
8 6 0.971807062625885 9.999999747378752e-05 0.0858895480632782 0.9864130616188049 0.05018732696771622
9 7 0.9765625 9.999999747378752e-05 0.07714884728193283 0.9836956262588501 0.05103155970573425
10 8 0.973505437374115 9.999999747378752e-05 0.07740459591150284 0.9823369383811951 0.053474295884370804
11 9 0.9806385636329651 4.999999873689376e-05 0.06630785763263702 0.9864130616188049 0.045486435294151306
12 10 0.9806385636329651 4.999999873689376e-05 0.058046672493219376 0.98777174949646 0.04103342071175575
13 11 0.9823369383811951 4.999999873689376e-05 0.055304937064647675 0.989130437374115 0.041949912905693054
14 12 0.9836956262588501 4.999999873689376e-05 0.05309256166219711 0.989130437374115 0.03986254334449768
15 13 0.9819973111152649 4.999999873689376e-05 0.05787506327033043 0.989130437374115 0.037597913295030594
16 14 0.98267662525177 4.999999873689376e-05 0.05659506097435951 0.991847813129425 0.03598109260201454
17 15 0.983016312122345 4.999999873689376e-05 0.05229465290904045 0.99048912525177 0.03660966083407402
18 16 0.9819973111152649 4.999999873689376e-05 0.05457111448049545 0.99048912525177 0.03671116754412651
19 17 0.98607337474823 2.499999936844688e-05 0.04707670584321022 0.98777174949646 0.03703512251377106
20 18 0.98879075050354 2.499999936844688e-05 0.04428504779934883 0.989130437374115 0.03504762053489685
21 19 0.9867526888847351 2.499999936844688e-05 0.04896799474954605 0.989130437374115 0.03598404303193092

View File

@ -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
1 epoch accuracy learning_rate loss val_accuracy val_loss
2 0 0.748641312122345 9.999999747378752e-05 0.6748814582824707 0.9510869383811951 0.1968584656715393
3 1 0.926630437374115 9.999999747378752e-05 0.23904117941856384 0.9660326242446899 0.12440376728773117
4 2 0.94972825050354 9.999999747378752e-05 0.1546500027179718 0.976902186870575 0.1011323630809784
5 3 0.960597813129425 9.999999747378752e-05 0.13199861347675323 0.9850543737411499 0.07602649927139282
6 4 0.9633151888847351 9.999999747378752e-05 0.11540684849023819 0.9741848111152649 0.07963371276855469
7 5 0.9677309989929199 9.999999747378752e-05 0.09640498459339142 0.9836956262588501 0.059806425124406815
8 6 0.9741848111152649 9.999999747378752e-05 0.08353486657142639 0.98097825050354 0.06453259289264679
9 7 0.9765625 9.999999747378752e-05 0.07739967107772827 0.979619562625885 0.0524170957505703
10 8 0.9786005616188049 9.999999747378752e-05 0.07381828129291534 0.9850543737411499 0.049863629043102264
11 9 0.979619562625885 9.999999747378752e-05 0.06559862196445465 0.9864130616188049 0.04981501027941704
12 10 0.9786005616188049 9.999999747378752e-05 0.06449061632156372 0.98097825050354 0.05683763697743416
13 11 0.98267662525177 4.999999873689376e-05 0.055478502064943314 0.9850543737411499 0.049218062311410904
14 12 0.98267662525177 4.999999873689376e-05 0.05234510824084282 0.9864130616188049 0.04511260613799095
15 13 0.984375 4.999999873689376e-05 0.05012645572423935 0.98777174949646 0.04537223279476166
16 14 0.9850543737411499 4.999999873689376e-05 0.04811901971697807 0.9864130616188049 0.04349565878510475
17 15 0.985733687877655 4.999999873689376e-05 0.04842999577522278 0.9864130616188049 0.040977030992507935
18 16 0.9867526888847351 4.999999873689376e-05 0.047277845442295074 0.9864130616188049 0.039208367466926575
19 17 0.985733687877655 4.999999873689376e-05 0.042227428406476974 0.9864130616188049 0.039824478328228
20 18 0.98777174949646 4.999999873689376e-05 0.039644014090299606 0.9850543737411499 0.03922777995467186
21 19 0.9850543737411499 2.499999936844688e-05 0.04659169539809227 0.9864130616188049 0.041244834661483765

View File

@ -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
1 epoch accuracy learning_rate loss val_accuracy val_loss
2 0 0.7214673757553101 9.999999747378752e-05 0.7529850006103516 0.94701087474823 0.21970611810684204
3 1 0.9191576242446899 9.999999747378752e-05 0.25084418058395386 0.95923912525177 0.12908491492271423
4 2 0.950067937374115 9.999999747378752e-05 0.16257192194461823 0.970108687877655 0.09431818127632141
5 3 0.9582201242446899 9.999999747378752e-05 0.13206881284713745 0.976902186870575 0.07742702215909958
6 4 0.9677309989929199 9.999999747378752e-05 0.10626088827848434 0.9741848111152649 0.06937189400196075
7 5 0.969089686870575 9.999999747378752e-05 0.09285038709640503 0.97826087474823 0.06072676554322243
8 6 0.9667119383811951 9.999999747378752e-05 0.09316759556531906 0.976902186870575 0.05902751162648201
9 7 0.9724864363670349 9.999999747378752e-05 0.07857637107372284 0.97826087474823 0.05389025807380676
10 8 0.976902186870575 9.999999747378752e-05 0.07135744392871857 0.98097825050354 0.05123810097575188
11 9 0.98267662525177 9.999999747378752e-05 0.06045383960008621 0.9823369383811951 0.04801933839917183
12 10 0.97995924949646 9.999999747378752e-05 0.06303825229406357 0.9836956262588501 0.04756370931863785
13 11 0.97826087474823 9.999999747378752e-05 0.06300406157970428 0.9823369383811951 0.04598434641957283
14 12 0.9806385636329651 9.999999747378752e-05 0.05282346531748772 0.9823369383811951 0.0442848727107048
15 13 0.9816576242446899 9.999999747378752e-05 0.05177825316786766 0.9836956262588501 0.044551920145750046
16 14 0.984714686870575 9.999999747378752e-05 0.04417676851153374 0.98097825050354 0.048150435090065
17 15 0.984375 4.999999873689376e-05 0.047107867896556854 0.9850543737411499 0.04266688972711563
18 16 0.9870923757553101 4.999999873689376e-05 0.03834306448698044 0.9850543737411499 0.04022631794214249
19 17 0.9898098111152649 4.999999873689376e-05 0.03330085054039955 0.9850543737411499 0.041328392922878265
20 18 0.9870923757553101 4.999999873689376e-05 0.040723804384469986 0.9850543737411499 0.03947565332055092
21 19 0.9898098111152649 4.999999873689376e-05 0.03469662740826607 0.9836956262588501 0.0406419076025486

16
backend/resize.py Normal file
View File

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

204
backend/segmentasi.py Normal file
View File

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

View File

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

View File

@ -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}%`;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More