oriastanjung commited on
Commit
0f4a8fd
1 Parent(s): b8ae546

fix concurency and asyncronous request

Browse files
Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.10.14-slim-bullseye
3
+
4
+ # Set the working directory in the container
5
+ WORKDIR /app
6
+
7
+
8
+ # Copy only requirements.txt to leverage Docker cache
9
+ COPY . .
10
+
11
+ # Install any needed packages specified in requirements.txt
12
+ RUN apt-get update -y
13
+ RUN apt-get install libgl1-mesa-glx libglib2.0-0 -y
14
+ RUN pip3 install --no-cache-dir -r requirements.txt
15
+
16
+
17
+
18
+ # Make port 5000 available to the world outside this container
19
+ EXPOSE 5000
20
+
21
+ # Run the application
22
+ CMD ["python3", "main.py"]
RBFNN_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eadfe824158874c70d40f9f40d6b7a8e0461ad2df80de29d7e26663576fb02e1
3
+ size 92710
controllerKlasifikasi.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ from sklearn.preprocessing import MinMaxScaler, LabelEncoder
4
+ from helper.ekstraksiBentuk import ekstrakBentuk
5
+ from helper.ekstraksiTekstur import ekstrakTekstur
6
+ # import pickle
7
+ from scipy.spatial.distance import cdist
8
+ from numpy.linalg import pinv
9
+
10
+ labels = ['Avicennia alba', 'Bruguiera cylindrica', 'Bruguiera gymnorrhiza','Lumnitzora littorea', 'Rhizophora apiculata', 'Rhizophora mucronata','Scyphyphora hydrophyllacea', 'Senoratia alba', 'Xylocarpus granatum']
11
+
12
+ # Load data from CSV file
13
+ def load_data(file_path):
14
+ df = pd.read_csv(file_path)
15
+ return df
16
+
17
+ # Preprocess data
18
+ def preprocess_data(df):
19
+ # Extract features and labels
20
+ X = df[['Panjang','Keliling','Diameter','Luas','Faktor bentuk',
21
+ 'ASM 0','ASM 45','ASM 90','ASM 135','Kontras 0','Kontras 45',
22
+ 'Kontras 90','Kontras 135','IDM 0','IDM 45','IDM 90','IDM 135','Entropy 0','Entropy 45','Entropy 90',
23
+ 'Entropy 135','Korelasi 0','Korelasi 45',
24
+ 'Korelasi 90','Korelasi 135']].values
25
+ y = df['Jenis'].values
26
+
27
+ # Standardize features
28
+ scaler = MinMaxScaler()
29
+ X = scaler.fit_transform(X)
30
+
31
+ # Encode labels
32
+ label_encoder = LabelEncoder()
33
+ y = label_encoder.fit_transform(y)
34
+
35
+ return X, y, scaler, label_encoder # Return scaler along with X, y, and label_encoder
36
+
37
+ # Define the RBFN class for multi-class classification
38
+ class RBFNN:
39
+ def __init__(self, input_size, hidden_size, output_size):
40
+ self.input_size = input_size
41
+ self.hidden_size = hidden_size
42
+ self.output_size = output_size
43
+ self.centers = None
44
+ self.width = None
45
+ self.weights = None
46
+
47
+ def _gaussian(self, X, centers, width):
48
+ return np.exp(-cdist(X, centers) ** 2 / (2 * (width ** 2)))
49
+
50
+ def _one_hot_encoding(self, y):
51
+ one_hot = np.zeros((y.shape[0], self.output_size))
52
+ for i, val in enumerate(y):
53
+ one_hot[i, val] = 1
54
+ return one_hot
55
+
56
+ def fit(self, X, y):
57
+ # Initialize centers using K-means
58
+ from sklearn.cluster import KMeans
59
+ kmeans = KMeans(n_clusters=self.hidden_size, random_state=42)
60
+ kmeans.fit(X)
61
+ self.centers = kmeans.cluster_centers_
62
+
63
+ # Calculate width
64
+ self.width = np.mean(cdist(self.centers, self.centers)) / np.sqrt(2 * self.hidden_size)
65
+
66
+ # Compute activations
67
+ phi = self._gaussian(X, self.centers, self.width)
68
+
69
+ # Solve for weights using Moore-Penrose pseudoinverse
70
+ phi_pseudo_inverse = pinv(phi)
71
+ one_hot_y = self._one_hot_encoding(y)
72
+ self.weights = np.dot(phi_pseudo_inverse, one_hot_y)
73
+
74
+ def predict(self, X):
75
+ phi = self._gaussian(X, self.centers, self.width)
76
+ predictions = np.dot(phi, self.weights)
77
+ return np.argmax(predictions, axis=1)
78
+
79
+ def save_model(self, file_path):
80
+ import pickle
81
+ with open(file_path, 'wb') as f:
82
+ pickle.dump((self.centers, self.width, self.weights), f)
83
+
84
+ @staticmethod
85
+ def load_model(file_path):
86
+ import pickle
87
+ with open(file_path, 'rb') as f:
88
+ centers, width, weights = pickle.load(f)
89
+ model = RBFNN(input_size=centers.shape[1], hidden_size=centers.shape[0], output_size=weights.shape[1])
90
+ model.centers = centers
91
+ model.width = width
92
+ model.weights = weights
93
+ return model
94
+
95
+ # Load and preprocess training data
96
+ train_file_path = "data_set.csv"
97
+ train_df = load_data(train_file_path)
98
+ X_train, y_train, scaler, label_encoder = preprocess_data(train_df)
99
+
100
+ # Load the model from the file
101
+ loaded_model = RBFNN.load_model('RBFNN_model.pkl')
102
+
103
+
104
+ def klasifikasiMangrove(image) :
105
+ major_axis_length,perimeter,diameter,area,shape_factor=ekstrakBentuk(image)
106
+ asm_result,kontras_result,idm_result,entropy_result,korelasi_result=ekstrakTekstur(image)
107
+
108
+
109
+ new_data = np.array([[major_axis_length,perimeter,diameter,area,shape_factor,asm_result[0],asm_result[1],asm_result[2],asm_result[3],kontras_result[0],kontras_result[1],kontras_result[2],kontras_result[3],idm_result[0],idm_result[1],idm_result[2],idm_result[3],entropy_result[0],entropy_result[1],entropy_result[2],entropy_result[3],korelasi_result[0],korelasi_result[1],korelasi_result[2],korelasi_result[3]]]) # Example
110
+ new_data_scaled = scaler.transform(new_data)
111
+ predicted_class = loaded_model.predict(new_data_scaled)
112
+ predicted_label = label_encoder.inverse_transform(predicted_class)
113
+
114
+
115
+ klasifikasi_mangrove =labels[predicted_label[0]-1]
116
+ id_mangrove = predicted_label[0]-1
117
+ print(major_axis_length,perimeter,diameter,area,shape_factor)
118
+
119
+ return klasifikasi_mangrove, id_mangrove
dataTanaman.json ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": 1,
4
+ "nama": "Avicennia alba",
5
+ "dekripsi": "Avicennia alba adalah salah satu jenis mangrove yang dapat tumbuh hingga mencapai ketinggian 25 meter dan tersebar luas. Pohon ini memiliki sistem perakaran horizontal yang kompleks serta akar nafas yang rumit. Akar nafasnya biasanya tipis dan berbentuk seperti jari atau asparagus, dilapisi oleh lentisel. Kulit kayu luarnya berwarna keabu-abuan atau coklat gelap, dengan beberapa bagian memiliki tonjolan kecil sementara bagian lainnya kadang-kadang memiliki permukaan yang halus. Pada batang yang tua, kadang-kadang ditemukan serbuk tipis.",
6
+ "ekologi": "Jenis ini adalah pionir di habitat rawa mangrove pada pantai yang terlindung, area yang lebih asin di sepanjang tepi sungai yang dipengaruhi pasang surut, serta sepanjang garis pantai. Mereka biasanya tumbuh subur di bagian depan teluk. Akar-akarnya diketahui membantu mengikat sedimen dan mempercepat proses pembentukan daratan. Tanaman ini berbunga sepanjang tahun. Genus ini kadang-kadang bersifat vivipar, di mana sebagian buah berkembang biak saat masih menempel pada pohon.",
7
+ "manfaat": "Batang dari jenis ini dapat digunakan sebagai kayu bakar dan bahan bangunan berkualitas rendah. Getahnya bisa dimanfaatkan sebagai alat kontrasepsi. Buahnya dapat dimakan.",
8
+ "penyebaran": "Ditemukan di seluruh Indonesia, India, Indo Cina, Malaysia, Filipina, Papua Nugini, dan Australia tropis.",
9
+ "imgSRC": "/gambar_data_tanaman/Avicennia alba.JPG"
10
+ },
11
+ {
12
+ "id": 2,
13
+ "nama": "Bruguiera cylindrica",
14
+ "dekripsi": "Bruguiera cylindrica memiliki akar lutut dan akar papan yang menyebar ke samping dari pangkal pohon, dengan ketinggian yang kadang-kadang mencapai 23 meter. Kulit kayunya berwarna abu-abu, relatif halus, dan memiliki sejumlah lentisel kecil.",
15
+ "ekologi": "Tumbuh mengelompok dalam jumlah besar, biasanya pada tanah liat di belakang zona Avicennia, atau di bagian tengah vegetasi mangrove kearah laut. Jenis ini juga memiliki kemampuan untuk tumbuh pada tanah/substrat yang baru terbentuk dan tidak cocok untuk jenis lainnya. Kemampuan tumbuhnya pada tanah liat membuat pohon jenis ini sangat bergantung kepada akar nafas untuk memperoleh pasokan oksigen yang cukup, dan oleh karena itu sangat responsif terhadap penggenangan yang berkepanjangan. Memiliki buah yang ringan dan mengapung sehinggga penyebarannya dapat dibantu oleh arus air, tapi pertumbuhannya lambat. Perbungaan terjadi sepanjang tahun.",
16
+ "manfaat": "Batang mangrove jenis ini dapat dimanfaatkan menjadi kayu bakar. Di beberapa daerah, akar muda dari embrionya dimakan dengan gula dan kelapa. Para nelayan tidak menggunakan kayunya untuk kepentingan penangkapan ikan karena kayu tersebut mengeluarkan bau yang menyebabkan ikan tidak mau mendekat.",
17
+ "penyebaran": "Tersebar di Asia Tenggara, Australia, dan seluruh Indonesia termasuk Irian Jaya.",
18
+ "imgSRC": "/gambar_data_tanaman/Bruguiera cylindrica.JPG"
19
+ },
20
+ {
21
+ "id": 3,
22
+ "nama": "Bruguiera gymnorrhiza",
23
+ "dekripsi": "Mangrove jenis ini dapat mencapau ketinggian 30 m. Kulit kayu memiliki lentisel, permukaannya halus hingga kasar, berwarna abu-abu tua sampai coklat (warna berubah-ubah). Akarnya seperti papan melebar ke samping di bagian pangkal pohon, juga memiliki sejumlah akar lutut.",
24
+ "ekologi": "Merupakan jenis yang dominan pada hutan mangrove yang tinggi dan merupakan ciri dari perkembangan tahap akhir dari hutan pantai, serta tahap awal dalam transisi menjadi tipe vegetasi daratan. Tumbuh di areal dengan salinitas rendah dan kering, serta tanah yang memiliki aerasi yang baik. Jenis ini toleran terhadap daerah terlindung maupun yang mendapat sinar matahari langsung. Mereka juga tumbuh pada tepi daratan dari mangrove, sepanjang tambak serta sungai pasang surut dan payau. Ditemukan di tepi pantai hanya jika terjadi erosi pada lahan di hadapannya. Substrat-nya terdiri dari lumpur, pasir dan kadang-kadang tanah gambut hitam. Kadang-kadang juga ditemukan di pinggir sungai yang kurang terpengaruh air laut, hal tersebut dimungkinkan karena buahnya terbawa arus air atau gelombang pasang. Regenerasinya seringkali hanya dalam jumlah terbatas. Bunga dan buah terdapat sepanjang tahun. Bunga relatif besar, memiliki kelopak bunga berwarna kemerahan, tergantung, dan mengundang burung untuk melakukan penyerbukan.",
25
+ "manfaat": "Bagian dalam hipokotil dimakan (manisan kandeka), dicampur dengan gula. Kayunya yang berwarna merah digunakan sebagai kayu bakar dan untuk membuat arang.",
26
+ "penyebaran": "Dari Afrika Timur dan Madagaskar hingga Sri Lanka, Malaysia, Indonesia, hingga ke Pasifik Barat dan Australia Tropis.",
27
+ "imgSRC": "/gambar_data_tanaman/Bruguiera gymnorrhiza.JPG"
28
+ },
29
+ {
30
+ "id": 4,
31
+ "nama": "Lumnitzera littorea",
32
+ "dekripsi": "Jenis ini tumbuh tersebar dan dapat mencapai ketinggian 25 m. m, meskipun pada umumnya lebih rendah. Akar nafas berbentuk lutut, berwarna coklat tua dan kulit kayu memiliki celah/retakan membujur (longitudinal).",
33
+ "ekologi": "Jenis ini seringkali ditemui ditempat dengan substrat halus dan berlumpur pada bagian pinggir daratan di daerah mangrove, dimana penggenangan jarang terjadi. Mereka juga terdapat pada jalur air yang memiliki pasokan air tawar yang kuat dan tetap. Perbungaan terjadi sepanjang tahun. Produksi nektar, warna bunga serta morfologi dan lokasinya menunjukkan bahwa penyerbukannya dibantu oleh burung. Buah yang ringan dan dapat mengapung sangat menunjang penyebaran mereka melalui air.",
34
+ "manfaat": "Kayunya kuat dan sangat tahan terhadap air. Dengan penampilannya yang menarik dan memiliki wangi seperti mawar, maka kayunya sangat cocok untuk dijadikan sebagai bahan pembuatan lemari dan furnitur lainnya. Sayangnya, kayu berukuran besar sangat jarang ditemukan.",
35
+ "penyebaran": "Di daerah tropis Asia, Indonesia, Australia Utara, dan Polinesia. Jarang dijumpai di pantai-pantai di Jawa.",
36
+ "imgSRC": "/gambar_data_tanaman/Lumnitzera littorea.JPG"
37
+ },
38
+ {
39
+ "id": 5,
40
+ "nama": "Rhizophora apiculata",
41
+ "dekripsi": "Jenis ini dapat mencapai ketinggian 30 m dengan diameter batang 50cm. Memiliki perakaran yang khas hingga mencapai ketinggian 5 meter, dan kadang-kadang memiliki akar udara yang keluar dari cabang. Kulit kayu berwarna abu-abu tua dan berubah-ubah.",
42
+ "ekologi": "Sering ditemui tumbuh pada tanah berlumpur, halus, dalam dan tergenang pada saat pasang normal. Tidak menyukai substrat yang lebih keras yang bercampur dengan pasir. Tingkat dominasi dapat mencapai 90% dari vegetasi yang tumbuh di suatu lokasi. Menyukai perairan pasang surut yang memiliki pengaruh masukan air tawar yang kuat secara permanen. Percabangan akarnya dapat tumbuh secara abnormal karena gangguan kumbang yang menyerang ujung akar. Kepiting dapat juga menghambat pertumbuhan mereka karena mengganggu kulit akar anakan. Tumbuh lambat, tetapi perbungaan terdapat sepanjang tahun.",
43
+ "manfaat": "Kayu dimanfaatkan untuk bahan bangunan, kayu bakar dan arang. Kulit kayu berisi hingga 30% tanin (per sen berat kering). Cabang akar dapat digunakan sebagai jangkar dengan diberati batu. Di Jawa acapkali ditanam di pinggiran tambak untuk melindungi pematang. Sering digunakan sebagai tanaman penghijauan.",
44
+ "penyebaran": "Dari Sri Lanka, Malaysia, Indonesia hingga Australia Tropis dan Kepulauan Pasifik."
45
+ ,
46
+ "imgSRC": "/gambar_data_tanaman/Rhizophora apiculata.JPG"
47
+
48
+ },
49
+ {
50
+ "id": 6,
51
+ "nama": "Rhizophora mucronata",
52
+ "dekripsi": "Jenis ini biasanya memiliki tinggi maksimal sepanjam 27 m, jarang melebihi 30 m. Batangnya dapat memiliki diameter hingga 70 cm. dengan kulit kayu berwarna gelap hingga hitam dan terdapat celah horizontal. Akar tunjang dan akar udara yang tumbuh dari percabangan bagian bawah.",
53
+ "ekologi": "Sering ditemui dihabitat yang sama dengan R. apiculata tetapi lebih toleran terhadap substrat yang lebih keras dan pasir. Pada umumnya tumbuh dalam kelompok, dekat atau pada pematang sungai pasang surut dan di muara sungai, jarang sekali tumbuh pada daerah yang jauh dari air pasang surut. Pertumbuhan optimal terjadi pada areal yang tergenang dalam, serta pada tanah yang kaya akan humus. Merupakan salah satu jenis tumbuhan mangrove yang paling penting dan paling tersebar luas. Perbungaan terjadi sepanjang tahun. Anakan seringkali dimakan oleh kepiting, sehingga menghambat pertumbuhan mereka. Anakan yang telah dikeringkan dibawah naungan untuk beberapa hari akan lebih tahan terhadap gangguan kepiting. Hal tersebut mungkin dikarenakan adanya akumulasi tanin dalam jaringan yang kemudian melindungi mereka.",
54
+ "manfaat": "Kayu digunakan sebagai bahan bakar dan arang. Tanin dari kulit kayu digunakan untuk pewarnaan, dan kadang-kadang digunakan sebagai obat dalam kasus hematuria (perdarahan pada air seni). Kadang-kadang ditanam di sepanjang tambak untuk melindungi pematang.",
55
+ "penyebaran": "Dari Afrika Timur, Asia Tenggara, seluruh Malaysia dan Indonesia, Melanesia, Mikronesia, hingga ditanam di Hawaii."
56
+ ,
57
+ "imgSRC": "/gambar_data_tanaman/Rhizophora mucronata.JPG"
58
+
59
+ },
60
+ {
61
+ "id": 7,
62
+ "nama": "Scyphiphora hydrophyllacea",
63
+ "dekripsi": "Jenis ini memiliki pohon semak tegak, memiliki banyak cabang, dan ketinggian maksimal mencapai 3 m. Kulit kayu kasar berwarna coklat, cabang muda memiliki resin, kadang-kadang terdapat akar tunjang pada individu yang besar.",
64
+ "ekologi": "Tumbuh pada substrat lumpur, pasir dan karang pada tepi daratan mangrove atau pada pematang dan dekat jalur air. Nampaknya tidak toleran terhadap penggenangan air tawar dalam waktu yang lama dan biasanya menempati lokasi yang kerap tergenang oleh pasang surut. Dilaporkan tumbuh pada lokasi yang tidak cocok untuk dikolonisasi oleh jenis tumbuhan mangrove lainnya. Perbungaan terdapat sepanjang tahun, kemungkinan diserbuki sendiri atau oleh serangga. Nektar diproduksi oleh cakram kelenjar pada pangkal mahkota bunga. Banyak buah yang dihasilkan, akan tetapi pembiakan biji relatif rendah. Buah teradaptasi dengan baik untuk penyebaran oleh air karena kulit buahnya yang ringan dan mengapung.",
65
+ "manfaat": "Kayu kemungkinan dapat digunakan untuk peralatan makan, seperti sendok. Daun dapat digunakan untuk mengatasi sakit perut.",
66
+ "penyebaran": "Ditemukan di India, Sri Lanka, Malaysia, Indonesia, Papua Nugini, Filipina, Kepulauan Solomon, dan Australia Tropis."
67
+ ,
68
+ "imgSRC": "/gambar_data_tanaman/Scyphyphora hydrophyllacea.JPG"
69
+
70
+ },
71
+ {
72
+ "id": 8,
73
+ "nama": "Sonneratia alba",
74
+ "dekripsi": "Mangrove jenis ini dapat mencapai ketinggian hingga 15 m. Kulit kayu berwarna putih tua hingga coklat, dengan celah longitudinal yang halus. Akar berbentuk kabel di bawah tanah dan muncul kepermukaan sebagai akar nafas yang berbentuk kerucut tumpul dan tingginya mencapai 25 cm.",
75
+ "ekologi": "Jenis pionir, tidak toleran terhadap air tawar dalam periode yang lama. Menyukai tanah yang bercampur lumpur dan pasir, kadang-kadang pada batuan dan karang. Sering ditemukan di lokasi pesisir yang terlindung dari hempasan gelombang, juga di muara dan sekitar pulau-pulau lepas pantai. Di lokasi dimana jenis tumbuhan lain telah ditebang, maka jenis ini dapat membentuk tegakan yang padat. Perbungaan terjadi sepanjang tahun. Bunga hidup tidak terlalu lama dan mengembang penuh di malam hari, mungkin diserbuki oleh ngengat, burung dan kelelawar pemakan buah. Di jalur pesisir yang berkarang mereka tersebar secara vegetatif. Kunang-kunang sering menempel pada pohon ini dikala malam. Buah mengapung karena adanya jaringan yang mengandung air pada bijinya. Akar nafas tidak terdapat pada pohon yang tumbuh pada substrat yang keras.",
76
+ "manfaat": "Buahnya asam dapat dimakan. Di Sulawesi, kayu dibuat untuk perahu dan bahan bangunan, atau sebagai bahan bakar ketika tidak ada bahan bakar lain. Akar nafas digunakan oleh orang Irian untuk gabus dan pelampung.",
77
+ "penyebaran": "Dari Afrika Utara, Madagaskar, Asia Tenggara, Indonesia, Malaysia, Filipina, Australia Tropis, hingga Oceania Barat Daya."
78
+ ,
79
+ "imgSRC": "/gambar_data_tanaman/Sonneratia alba.JPG"
80
+
81
+ },
82
+ {
83
+ "id": 9,
84
+ "nama": "Xylocarpus granatum",
85
+ "dekripsi": "Pohon dapat mencapai ketinggian 10-20 m. Memiliki akar papan yang melebar ke samping, meliuk-liuk dan membentuk celahan-celahan. Batang seringkali berlubang, khususnya pada pohon yang lebih tua. Kulit kayu berwarna coklat muda-kekuningan, tipis dan mengelupas, sementara pada cabang yang muda, kulit kayu berkeriput.",
86
+ "ekologi": "Tumbuh di sepanjang pinggiran sungai pasang surut, pinggir daratan dari mangrove, dan lingkungan payau lainnya yang tidak terlalu asin. Seringkali tumbuh mengelompok dalam jumlah besar. Individu yang telah tua seringkali ditumbuhi oleh epifit.",
87
+ "manfaat": "Kayunya hanya tersedia dalam ukuran kecil, kadang-kadang digunakan sebagai bahan pembuatan perahu. Kulit kayu dikumpulkan karena kandungan taninnya yang tinggi (>24% berat kering).",
88
+ "penyebaran": "Tumbuh di Jawa, Madura, Bali, Karimun Jawa, Sumatera, Sulawesi, Kalimantan, Maluku, Sumba, dan Irian Jaya."
89
+ ,
90
+ "imgSRC": "/gambar_data_tanaman/Xylocarpus granatum.JPG"
91
+
92
+ }
93
+ ]
data_set.csv ADDED
The diff for this file is too large to render. See raw diff
 
gambar_data_tanaman/Avicennia alba.JPG ADDED
gambar_data_tanaman/Bruguiera cylindrica.JPG ADDED
gambar_data_tanaman/Bruguiera gymnorrhiza.JPG ADDED
gambar_data_tanaman/Lumnitzera littorea.JPG ADDED
gambar_data_tanaman/Rhizophora apiculata.JPG ADDED
gambar_data_tanaman/Rhizophora mucronata.JPG ADDED
gambar_data_tanaman/Scyphyphora hydrophyllacea.JPG ADDED
gambar_data_tanaman/Sonneratia alba.JPG ADDED
gambar_data_tanaman/Xylocarpus granatum.JPG ADDED
gunicorn.conf.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ bind = "0.0.0.0:8080"
2
+ workers = 2
helper/__pycache__/ekstraksiBentuk.cpython-310.pyc ADDED
Binary file (1.54 kB). View file
 
helper/__pycache__/ekstraksiBentuk.cpython-311.pyc ADDED
Binary file (2.92 kB). View file
 
helper/__pycache__/ekstraksiTekstur.cpython-310.pyc ADDED
Binary file (1.67 kB). View file
 
helper/__pycache__/ekstraksiTekstur.cpython-311.pyc ADDED
Binary file (3.44 kB). View file
 
helper/ekstraksiBentuk.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ from skimage import exposure
4
+ import os
5
+ from scipy.spatial import distance
6
+
7
+ def ekstrakBentuk(image):
8
+ # Load the image in grayscale
9
+ resized_image = cv2.resize(image, (512, 512)) # Resize the image to 512x512
10
+ imageGray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
11
+
12
+
13
+ # Apply Gaussian Blur to reduce noise
14
+ blurred_image = cv2.GaussianBlur(imageGray, (5, 5), 0)
15
+
16
+ # Apply histogram equalization to improve contrast
17
+ equalized_image = exposure.equalize_hist(blurred_image)
18
+ equalized_image = (equalized_image * 255).astype(np.uint8)
19
+
20
+ # Apply Sobel operator to detect edges
21
+ sobel_x = cv2.Sobel(equalized_image, cv2.CV_64F, 1, 0, ksize=5)
22
+ sobel_y = cv2.Sobel(equalized_image, cv2.CV_64F, 0, 1, ksize=5)
23
+ sobel = np.hypot(sobel_x, sobel_y)
24
+ sobel = np.uint8(sobel / np.max(sobel) * 255)
25
+
26
+ # Find contours in the Sobel image
27
+ contours, _ = cv2.findContours(sobel, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
28
+
29
+ # Assuming we are interested in the largest contour
30
+ contour = max(contours, key=cv2.contourArea)
31
+
32
+ # Calculate moments to find the centroid
33
+ M = cv2.moments(contour)
34
+ if M["m00"] != 0:
35
+ cx = int(M["m10"] / M["m00"])
36
+ cy = int(M["m01"] / M["m00"])
37
+ else:
38
+ cx, cy = 0, 0
39
+
40
+ # Calculate area
41
+ area = M["m00"]
42
+
43
+ # Calculate perimeter (length)
44
+ perimeter = cv2.arcLength(contour, True)
45
+
46
+ # Calculate the major axis length
47
+ distances = [distance.euclidean((cx, cy), point[0]) for point in contour]
48
+ major_axis_length = max(distances)
49
+
50
+ # Calculate the minor axis length
51
+ minor_axis_length = min(distances)
52
+
53
+ # Calculate diameter
54
+ diameter = (major_axis_length + minor_axis_length) / 2
55
+
56
+ # Calculate shape factor
57
+ shape_factor = (perimeter ** 2) / (4 * np.pi * area)
58
+
59
+
60
+ return major_axis_length, perimeter, diameter, area, shape_factor
61
+
62
+
helper/ekstraksiTekstur.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import os
4
+ from skimage.feature import graycomatrix
5
+
6
+ def calculate_glcm_features(glcm):
7
+ # Mendapatkan jumlah level abu-abu
8
+ L = glcm.shape[0]
9
+
10
+ # Inisialisasi variabel fitur
11
+ asm = 0
12
+ contrast = 0
13
+ idm = 0
14
+ entropy = 0
15
+ correlation = 0
16
+
17
+ # Mean dan standar deviasi untuk perhitungan korelasi
18
+ px = np.sum(glcm, axis=1)
19
+ py = np.sum(glcm, axis=0)
20
+ mean_i = np.sum(np.arange(L) * px)
21
+ mean_j = np.sum(np.arange(L) * py)
22
+ std_i = np.sqrt(np.sum((np.arange(L) - mean_i)**2 * px))
23
+ std_j = np.sqrt(np.sum((np.arange(L) - mean_j)**2 * py))
24
+
25
+ # Menghitung fitur GLCM
26
+ for i in range(L):
27
+ for j in range(L):
28
+ p_ij = glcm[i, j]
29
+ if p_ij > 0:
30
+ asm += p_ij**2
31
+ contrast += (i - j)**2 * p_ij
32
+ idm += p_ij / (1 + (i - j)**2)
33
+ entropy -= p_ij * np.log2(p_ij)
34
+ correlation += ((i - mean_i) * (j - mean_j) * p_ij) / (std_i * std_j)
35
+
36
+ return asm, contrast, idm, entropy, correlation
37
+
38
+ def ekstrakTekstur(image):
39
+ # Memuat gambar dalam grayscale
40
+ imageGray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
41
+
42
+ # Resize gambar ke ukuran yang diinginkan (misalnya 512x512)
43
+ image_resized = cv2.resize(imageGray, (512, 512))
44
+
45
+ # Mendefinisikan jarak dan sudut untuk perhitungan GLCM
46
+ distances = [1] # Menggunakan berbagai jarak
47
+ angles = [0, np.pi/4, np.pi/2, 3*np.pi/4] # 0, 45, 90, 135 derajat
48
+
49
+ # Inisialisasi array untuk menyimpan fitur untuk setiap sudut dan jarak
50
+ asm_result = []
51
+ kontras_result = []
52
+ idm_result = []
53
+ entropy_result = []
54
+ korelasi_result = []
55
+
56
+ # Menghitung GLCM dan mengekstraksi fitur
57
+ for distance in distances:
58
+ glcm = graycomatrix(image_resized, [distance], angles, 256, symmetric=True, normed=True)
59
+ for angle_idx in range(len(angles)):
60
+ asm, contrast, idm, entropy, correlation = calculate_glcm_features(glcm[:, :, 0, angle_idx])
61
+ asm_result.append(asm)
62
+ kontras_result.append(contrast)
63
+ idm_result.append(idm)
64
+ entropy_result.append(entropy)
65
+ korelasi_result.append(correlation)
66
+ print(entropy_result)
67
+ return asm_result, kontras_result, idm_result, entropy_result, korelasi_result
68
+
69
+
main.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from quart import Quart, request, jsonify, send_from_directory, Blueprint
2
+ from quart_cors import cors
3
+ import json
4
+ import base64
5
+ # import os
6
+ import numpy as np
7
+ import cv2
8
+ import asyncio
9
+ import aiofiles
10
+ from controllerKlasifikasi import klasifikasiMangrove
11
+
12
+ app = Quart(__name__)
13
+ cors(app, allow_origin="*") # Mengaktifkan CORS
14
+
15
+ # Buat blueprint untuk file statis
16
+ static_bp = Blueprint('static', __name__, static_folder='gambar_data_tanaman')
17
+
18
+ # Tambahkan route untuk menyajikan gambar
19
+ @static_bp.route('/gambar_data_tanaman/<path:filename>')
20
+ async def serve_image(filename):
21
+ return await send_from_directory(static_bp.static_folder, filename)
22
+
23
+ # Daftarkan blueprint ke aplikasi Quart
24
+ app.register_blueprint(static_bp)
25
+
26
+ @app.route('/', methods=['GET'])
27
+ async def index():
28
+ return jsonify("hello world")
29
+
30
+ @app.route('/mangrove/get-data', methods=['GET'])
31
+ async def get_data():
32
+ async with aiofiles.open('dataTanaman.json', 'r') as file:
33
+ data = await file.read()
34
+ return jsonify(json.loads(data))
35
+
36
+ @app.route('/mangrove/upload-image', methods=['POST'])
37
+ async def upload_image():
38
+ request_json = await request.json
39
+ if 'image' not in request_json:
40
+ return jsonify({"error": "No image part in the request"}), 400
41
+
42
+ image_b64 = request_json['image']
43
+ # Decode base64 to image data
44
+ image_data = base64.b64decode(image_b64)
45
+
46
+ # Convert image data to OpenCV format
47
+ nparr = np.frombuffer(image_data, np.uint8)
48
+ img_cv = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
49
+
50
+ # Perform classification (synchronously)
51
+ klasifikasi_mangrove, id_mangrove = await asyncio.to_thread(klasifikasiMangrove, img_cv)
52
+
53
+ # Load dataTanaman.json
54
+ async with aiofiles.open('dataTanaman.json', 'r') as file:
55
+ data_tanaman_json = await file.read()
56
+ data_tanaman = json.loads(data_tanaman_json)
57
+
58
+ # Find data by ID
59
+ result_data = None
60
+ for data in data_tanaman:
61
+ if data['id'] == id_mangrove + 1:
62
+ result_data = data
63
+ break
64
+
65
+ if result_data:
66
+ return jsonify({
67
+ "message": "Sukses Klasifikasi Mangrove!",
68
+ "result": str(klasifikasi_mangrove),
69
+ "id": str(id_mangrove + 1),
70
+ "data_tanaman": result_data
71
+ })
72
+ else:
73
+ return jsonify({
74
+ "message": "Sukses Klasifikasi Mangrove!",
75
+ "result": str(klasifikasi_mangrove),
76
+ "id": str(id_mangrove),
77
+ "data_tanaman": "Data not found for ID " + str(id_mangrove + 1)
78
+ })
79
+
80
+ if __name__ == '__main__':
81
+ app.run(host='0.0.0.0', debug=True, port=5000)
readme copy.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # INSTALLATION
2
+
3
+ pip install -r requirements.txt
4
+
5
+ python main.py
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ flask
2
+ scikit-learn
3
+ scikit-image
4
+ flask_cors
5
+ numpy
6
+ opencv-python
7
+ scipy
8
+ pandas
9
+ quart
10
+ quart_cors
vercel.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 2,
3
+ "builds": [
4
+ {
5
+ "src": "main.py",
6
+ "use": "@vercel/python"
7
+ }
8
+ ],
9
+ "routes": [
10
+ {
11
+ "src": "/(.*)",
12
+ "dest": "main.py"
13
+ }
14
+ ]
15
+ }