diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 77626300429d73ceaf9f03bbd4ddf8af412cfffd..2b4faaa151cf07bc638245989c239f22429b6ff1 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,7 +4,7 @@ <selectionStates> <SelectionState runConfigName="app"> <option name="selectionMode" value="DROPDOWN" /> - <DropdownSelection timestamp="2025-01-07T00:07:51.508741600Z"> + <DropdownSelection timestamp="2025-01-07T01:25:25.467972600Z"> <Target type="DEFAULT_BOOT"> <handle> <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Prosp\.android\avd\Pixel_8a_API_35.avd" /> diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3cef3fdeb70e696e4bebaa6df4e6485448e1d1b7..41dbf8598cbdca8cdbec2adf7d88fb2d77ea9e51 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,7 +38,7 @@ android:name=".HomeActivity" android:screenOrientation="portrait" /> <activity - android:name=".TutorialActivity" + android:name=".tutorials.TutorialActivity" android:screenOrientation="portrait" /> <activity android:name=".PublicActivity" diff --git a/app/src/main/java/com/example/myapplication/HomeActivity.java b/app/src/main/java/com/example/myapplication/HomeActivity.java index 8bef76f8915a35f73ba547e15bd381f253907de9..976416a8435208ece3fdbf0b589354900f5bb917 100644 --- a/app/src/main/java/com/example/myapplication/HomeActivity.java +++ b/app/src/main/java/com/example/myapplication/HomeActivity.java @@ -9,31 +9,62 @@ import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; +import com.example.myapplication.tutorials.TutorialActivity; + +/** + * HomeActivity represents the main screen of the application where users can access + * various sections of the app, such as Learning, Stats, Settings, and Photo. The activity + * also handles displaying tutorials for first-time users or specific navigation flows. + */ public class HomeActivity extends AppCompatActivity { + + /** + * Called when the activity is resumed. It checks if a tutorial should be shown based + * on the user's previous interactions or the source of the current intent (e.g., from the photo page). + * If the tutorial is needed, it is triggered. + */ @Override protected void onResume() { super.onResume(); - // If tutorial ran from photo page + // If tutorial ran from photo page, show the tutorial boolean fromPhotoPage = getIntent().getBooleanExtra("FROM_PHOTO_PAGE", false); if (fromPhotoPage) runTutorial(true); String tutorialKey = "FIRST_TIME_TUTORIAL"; - boolean preferences = getIntent().getBooleanExtra("PREFERENCES",true); + boolean preferences = getIntent().getBooleanExtra("PREFERENCES", true); + + // If preferences is false, skip the tutorial on the first time if (!preferences) getPreferences(MODE_PRIVATE).edit().putBoolean(tutorialKey, false).apply(); + boolean firstTime = getPreferences(MODE_PRIVATE).getBoolean(tutorialKey, true); + + // Run the tutorial if it's the first time using the app if (firstTime) { runTutorial(false); } } + /** + * Starts the TutorialActivity to display a tutorial. + * It checks if the tutorial is to be shown due to navigating from the photo page. + * + * @param fromPhotoPage A boolean that specifies whether the tutorial is shown due to navigation from the photo page. + */ private void runTutorial(boolean fromPhotoPage) { - Intent intent = new Intent(HomeActivity.this, TutorialActivity.class); - intent.putExtra("FROM_PHOTO_PAGE", fromPhotoPage); - startActivity(intent); - finish(); + Intent intent = new Intent(HomeActivity.this, TutorialActivity.class); + intent.putExtra("FROM_PHOTO_PAGE", fromPhotoPage); + startActivity(intent); + finish(); } + /** + * Called when the activity is created. This method sets up the theme based on user preferences, + * initializes the UI, and sets click listeners for each button to navigate to different pages. + * + * @param savedInstanceState A bundle containing the saved state of the activity, + * or null if there was no previously saved state. + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -45,12 +76,10 @@ public class HomeActivity extends AppCompatActivity { setContentView(R.layout.activity_home); - /* - On click listener for the Learning Button to open the "Apprendre" page by clicking - on the "Apprendre" button on the home page - */ - Button learningButton=(Button)findViewById(R.id.learning_button); - View.OnClickListener listenerLearningButton=new View.OnClickListener() { + // On click listener for the Learning Button to open the "Apprendre" page by clicking + // on the "Apprendre" button on the home page + Button learningButton = (Button) findViewById(R.id.learning_button); + View.OnClickListener listenerLearningButton = new View.OnClickListener() { @Override public void onClick(View view) { goToPage("LearningPage"); @@ -58,12 +87,10 @@ public class HomeActivity extends AppCompatActivity { }; learningButton.setOnClickListener(listenerLearningButton); - /* - On click listener for the Stats Button to open the "Statistiques" page by clicking - on the "Statistiques" button on the home page - */ - Button statsButton=(Button)findViewById(R.id.stats_button); - View.OnClickListener listenerStatsButton=new View.OnClickListener() { + // On click listener for the Stats Button to open the "Statistiques" page by clicking + // on the "Statistiques" button on the home page + Button statsButton = (Button) findViewById(R.id.stats_button); + View.OnClickListener listenerStatsButton = new View.OnClickListener() { @Override public void onClick(View view) { goToPage("StatsPage"); @@ -71,12 +98,10 @@ public class HomeActivity extends AppCompatActivity { }; statsButton.setOnClickListener(listenerStatsButton); - /* - On click listener for the Settings Button to open the "Paramètres" page by clicking - on the "Paramètres" button on the home page - */ - Button settingsButton=(Button)findViewById(R.id.settings_button); - View.OnClickListener listenerSettingsButton=new View.OnClickListener() { + // On click listener for the Settings Button to open the "Paramètres" page by clicking + // on the "Paramètres" button on the home page + Button settingsButton = (Button) findViewById(R.id.settings_button); + View.OnClickListener listenerSettingsButton = new View.OnClickListener() { @Override public void onClick(View view) { goToPage("SettingsPage"); @@ -84,12 +109,10 @@ public class HomeActivity extends AppCompatActivity { }; settingsButton.setOnClickListener(listenerSettingsButton); - /* - On click listener for the Photo Button to open the "Documenter" page by clicking - on the "Documenter" button on the home page - */ - Button photoButton=(Button)findViewById(R.id.photo_button); - View.OnClickListener listenerPhotoButton=new View.OnClickListener() { + // On click listener for the Photo Button to open the "Documenter" page by clicking + // on the "Documenter" button on the home page + Button photoButton = (Button) findViewById(R.id.photo_button); + View.OnClickListener listenerPhotoButton = new View.OnClickListener() { @Override public void onClick(View view) { goToPage("PhotoPage"); @@ -97,9 +120,12 @@ public class HomeActivity extends AppCompatActivity { }; photoButton.setOnClickListener(listenerPhotoButton); } + /** - * A method to go to the learning page - * @param pageToGo a string to signify to which page we want to go + * Navigates the user to the specified page by opening the PublicActivity + * and passing the target fragment as an extra. + * + * @param pageToGo A string representing the target page (fragment) to navigate to. */ public void goToPage(String pageToGo) { Intent intent = new Intent(HomeActivity.this, PublicActivity.class); diff --git a/app/src/main/java/com/example/myapplication/LearningPage.java b/app/src/main/java/com/example/myapplication/LearningPage.java index de979da49d19f8b22a1e4a2ee744be470caa0dd1..a1f490c6205f00116c1f4136c28a1aaa0a4014e3 100644 --- a/app/src/main/java/com/example/myapplication/LearningPage.java +++ b/app/src/main/java/com/example/myapplication/LearningPage.java @@ -11,7 +11,30 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import com.example.myapplication.overlays.OverlayDialogFragmentBecasseau; +import com.example.myapplication.overlays.OverlayDialogFragmentBernache; +import com.example.myapplication.overlays.OverlayDialogFragmentChevalier; +import com.example.myapplication.overlays.OverlayDialogFragmentCormoran; +import com.example.myapplication.overlays.OverlayDialogFragmentFoulque; +import com.example.myapplication.overlays.OverlayDialogFragmentGoeland; +import com.example.myapplication.overlays.OverlayDialogFragmentMouette; +import com.example.myapplication.overlays.OverlayDialogFragmentPluvier; +import com.example.myapplication.overlays.OverlayDialogFragmentTadorne; + +/** + * This fragment represents a learning page where the user can interact with different buttons. + * Each button triggers a dialog showing detailed information about a particular bird species. + */ public class LearningPage extends Fragment { + + /** + * Inflates the layout for this fragment. + * + * @param inflater The LayoutInflater object that can be used to inflate views in the fragment. + * @param container The parent container that the fragment's UI should be attached to. + * @param savedInstanceState A bundle containing the state of the fragment. + * @return The root view of the fragment's layout. + */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -19,158 +42,176 @@ public class LearningPage extends Fragment { return inflater.inflate(R.layout.fragment_learning_page, container, false); } + /** + * Sets up the listeners for each button on the learning page. Each listener triggers the display + * of a corresponding overlay dialog fragment for a bird species. + * + * @param view The root view of the fragment. + * @param savedInstanceState A bundle containing the state of the fragment. + */ @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - // Listener pour le becasseau + + // Set up the listener for the Becasseau button Button buttonBecasseau = (Button) this.getView().findViewById(R.id.button_becasseau); - View.OnClickListener listenerButtonBecasseau=new View.OnClickListener() { + View.OnClickListener listenerButtonBecasseau = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayBecasseau(); } }; - buttonBecasseau.setOnClickListener(listenerButtonBecasseau); - // Listener pour la bernache + // Set up the listener for the Bernache button Button buttonBernache = (Button) this.getView().findViewById(R.id.button_bernache); - - View.OnClickListener listenerButtonBernache=new View.OnClickListener() { + View.OnClickListener listenerButtonBernache = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayBernache(); } }; - buttonBernache.setOnClickListener(listenerButtonBernache); - // Listener pour le goeland + // Set up the listener for the Goeland button Button buttonGoeland = (Button) this.getView().findViewById(R.id.button_goeland); - - View.OnClickListener listenerButtonGoeland=new View.OnClickListener() { + View.OnClickListener listenerButtonGoeland = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayGoeland(); } }; - buttonGoeland.setOnClickListener(listenerButtonGoeland); - // Listener pour la mouette + // Set up the listener for the Mouette button Button buttonMouette = (Button) this.getView().findViewById(R.id.button_mouette); - - View.OnClickListener listenerButtonMouette=new View.OnClickListener() { + View.OnClickListener listenerButtonMouette = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayMouette(); } }; - buttonMouette.setOnClickListener(listenerButtonMouette); - // Listener pour le pluvier + // Set up the listener for the Pluvier button Button buttonPluvier = (Button) this.getView().findViewById(R.id.button_pluvier); - - View.OnClickListener listenerButtonPluvier=new View.OnClickListener() { + View.OnClickListener listenerButtonPluvier = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayPluvier(); } }; - buttonPluvier.setOnClickListener(listenerButtonPluvier); - // Listener pour le cormoran + // Set up the listener for the Cormoran button Button buttonCormoran = (Button) this.getView().findViewById(R.id.button_cormoran); - - View.OnClickListener listenerButtonCormoran=new View.OnClickListener() { + View.OnClickListener listenerButtonCormoran = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayCormoran(); } }; - buttonCormoran.setOnClickListener(listenerButtonCormoran); - // Listener pour la foulque macroule + // Set up the listener for the Foulque button Button buttonFoulque = (Button) this.getView().findViewById(R.id.button_foulque); - - View.OnClickListener listenerButtonFoulque=new View.OnClickListener() { + View.OnClickListener listenerButtonFoulque = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayFoulque(); } }; - buttonFoulque.setOnClickListener(listenerButtonFoulque); - // Listener pour le tadorne de Belon + // Set up the listener for the Tadorne button Button buttonTadorne = (Button) this.getView().findViewById(R.id.button_tadorne); - - View.OnClickListener listenerButtonTadorne=new View.OnClickListener() { + View.OnClickListener listenerButtonTadorne = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayTadorne(); } }; - buttonTadorne.setOnClickListener(listenerButtonTadorne); - // Listener pour le chevalier gambette + // Set up the listener for the Chevalier button Button buttonChevalier = (Button) this.getView().findViewById(R.id.button_chevalier); - - View.OnClickListener listenerButtonChevalier=new View.OnClickListener() { + View.OnClickListener listenerButtonChevalier = new View.OnClickListener() { @Override public void onClick(View view) { showOverlayChevalier(); } }; - buttonChevalier.setOnClickListener(listenerButtonChevalier); } + /** + * Shows an overlay dialog for the Becasseau bird species. + */ public void showOverlayBecasseau() { OverlayDialogFragmentBecasseau overlayDialogBecasseau = new OverlayDialogFragmentBecasseau(); overlayDialogBecasseau.show(getParentFragmentManager(), "overlayDialogBecasseau"); } + /** + * Shows an overlay dialog for the Bernache bird species. + */ public void showOverlayBernache() { OverlayDialogFragmentBernache overlayDialogBernache = new OverlayDialogFragmentBernache(); overlayDialogBernache.show(getParentFragmentManager(), "overlayDialogBernache"); } + /** + * Shows an overlay dialog for the Goeland bird species. + */ public void showOverlayGoeland() { OverlayDialogFragmentGoeland overlayDialogGoeland = new OverlayDialogFragmentGoeland(); overlayDialogGoeland.show(getParentFragmentManager(), "overlayDialogGoeland"); } + /** + * Shows an overlay dialog for the Mouette bird species. + */ public void showOverlayMouette() { OverlayDialogFragmentMouette overlayDialogMouette = new OverlayDialogFragmentMouette(); overlayDialogMouette.show(getParentFragmentManager(), "overlayDialogMouette"); } + /** + * Shows an overlay dialog for the Pluvier bird species. + */ public void showOverlayPluvier() { OverlayDialogFragmentPluvier overlayDialogPluvier = new OverlayDialogFragmentPluvier(); overlayDialogPluvier.show(getParentFragmentManager(), "overlayDialogPluvier"); } + /** + * Shows an overlay dialog for the Cormoran bird species. + */ public void showOverlayCormoran() { OverlayDialogFragmentCormoran overlayDialogCormoran = new OverlayDialogFragmentCormoran(); overlayDialogCormoran.show(getParentFragmentManager(), "overlayDialogCormoran"); } + /** + * Shows an overlay dialog for the Foulque bird species. + */ public void showOverlayFoulque() { OverlayDialogFragmentFoulque overlayDialogFoulque = new OverlayDialogFragmentFoulque(); overlayDialogFoulque.show(getParentFragmentManager(), "overlayDialogFoulque"); } + /** + * Shows an overlay dialog for the Tadorne bird species. + */ public void showOverlayTadorne() { OverlayDialogFragmentTadorne overlayDialogTadorne = new OverlayDialogFragmentTadorne(); overlayDialogTadorne.show(getParentFragmentManager(), "overlayDialogTadorne"); } + /** + * Shows an overlay dialog for the Chevalier bird species. + */ public void showOverlayChevalier() { OverlayDialogFragmentChevalier overlayDialogChevalier = new OverlayDialogFragmentChevalier(); overlayDialogChevalier.show(getParentFragmentManager(), "overlayDialogChevalier"); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/myapplication/MainActivity.java b/app/src/main/java/com/example/myapplication/MainActivity.java index 2393421f0775fde36c0b4172cb35b99ff500786c..3ff2cfb7a8d9b2d5849ca2cfec3b684f2afb1fa4 100644 --- a/app/src/main/java/com/example/myapplication/MainActivity.java +++ b/app/src/main/java/com/example/myapplication/MainActivity.java @@ -2,23 +2,27 @@ package com.example.myapplication; import android.content.Intent; import android.content.SharedPreferences; -import android.graphics.Bitmap; import android.os.Bundle; import android.os.Handler; -import android.view.View; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; -import org.tensorflow.lite.support.tensorbuffer.TensorBuffer; - -import java.io.IOException; -import java.util.List; - +/** + * The MainActivity class represents the main entry point of the application. + * It is responsible for loading the theme preference and transitioning to the HomeActivity + * after a brief delay. + */ public class MainActivity extends AppCompatActivity { + + /** + * Called when the activity is first created. This method is used to initialize + * the app's settings, including theme preferences, and to set up a delayed transition + * to the HomeActivity. + * + * @param savedInstanceState A bundle containing the saved state of the activity, + * or null if there was no previously saved state. + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -26,25 +30,29 @@ public class MainActivity extends AppCompatActivity { // Load the saved theme mode from SharedPreferences SharedPreferences preferences = getSharedPreferences("theme_prefs", MODE_PRIVATE); int themeMode = preferences.getInt("theme_mode", AppCompatDelegate.MODE_NIGHT_NO); + + // Apply the saved theme mode to the app AppCompatDelegate.setDefaultNightMode(themeMode); + // Set the content view to the layout for this activity setContentView(R.layout.activity_main); + // Delay time before transitioning to HomeActivity (in milliseconds) int delayMillis = 3000; + // Create a new handler to delay the transition to HomeActivity new Handler().postDelayed(new Runnable() { @Override public void run() { + // Create an intent to launch HomeActivity Intent intent = new Intent(MainActivity.this, HomeActivity.class); - startActivity(intent); - finish(); - } - }, delayMillis); - + // Start HomeActivity + startActivity(intent); + // Finish MainActivity so that it won't remain in the back stack + finish(); + } + }, delayMillis); // Delay the transition by the specified time } - - - } diff --git a/app/src/main/java/com/example/myapplication/PhotoPage.java b/app/src/main/java/com/example/myapplication/PhotoPage.java index 7dea134080e4ef2a9f51ce4ad17bf18ddf2ec369..199b9f9260f62cbed84ccda198e6765c5fb507f9 100644 --- a/app/src/main/java/com/example/myapplication/PhotoPage.java +++ b/app/src/main/java/com/example/myapplication/PhotoPage.java @@ -8,7 +8,12 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import com.example.myapplication.R; + +import com.example.myapplication.overlays.OverlayDialogFragmentForm; +import com.example.myapplication.recognation_logic.NoSpeciesRecognizedException; +import com.example.myapplication.recognation_logic.OutputPredictedImage; +import com.example.myapplication.recognation_logic.RecognizeSpecie; +import com.example.myapplication.recognation_logic.TestModeleTflite; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -24,7 +29,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.Spinner; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; @@ -33,6 +37,10 @@ import android.widget.Toast; import java.io.IOException; import java.util.Map; +/** + * A Fragment class responsible for capturing photos, selecting images from the gallery, + * processing them, and displaying species recognition results. + */ public class PhotoPage extends Fragment { private static final int CAMERA_REQUEST_CODE = 3; private static final int GALLERY_REQUEST_CODE = 1; @@ -49,14 +57,22 @@ public class PhotoPage extends Fragment { private Map<String, RecognizeSpecie> predictionResults; TableLayout tablePredictionResults; - int imageSize = 256; + /** + * Inflates the layout and initializes UI components for the fragment. + * + * @param inflater LayoutInflater for inflating the layout. + * @param container Parent container for the fragment. + * @param savedInstanceState Saved state of the fragment. + * @return The view for the fragment. + */ @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { predictionOutput = null; View view = inflater.inflate(R.layout.fragment_photo_page, container, false); + // Initialize UI elements cameraButton = view.findViewById(R.id.camera_button); folderButton = view.findViewById(R.id.folder_button); @@ -67,17 +83,18 @@ public class PhotoPage extends Fragment { imageView = view.findViewById(R.id.main_image_display); Button seeTutoButton = view.findViewById(R.id.see_tuto); - - // Set up button click listeners cameraButton.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.M) @Override public void onClick(View v) { + // Check for camera permission and request it if necessary if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { + // Start the camera activity if permission is granted Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE); } else { + // Request camera permission if not granted requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE); } } @@ -86,30 +103,26 @@ public class PhotoPage extends Fragment { folderButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + // Open the gallery to pick an image Intent folderIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(folderIntent, GALLERY_REQUEST_CODE); - } }); - /* identifiedSpeciesButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + // Display the identified species or a message if no species is recognized if(predictionOutput == null){ Toast.makeText(getContext(), "Veuillez prendre une photo ou charger une image depuis votre gallerie.", Toast.LENGTH_LONG).show(); } - if(outputPredictedImage != null){ - ResultsFragment resultsFragment = new ResultsFragment(outputPredictedImage.getPredictionResults()); - requireActivity().getSupportFragmentManager() - .beginTransaction() - .replace(R.id.fragment_container, resultsFragment) // Assuming you have a container in your activity layout - .addToBackStack(null) - .commit(); + else { + Toast.makeText(getContext(), predictionOutput, Toast.LENGTH_LONG).show(); } - } - });*/ + }); + + // Set up tutorial button View.OnClickListener lSeeTutoButton = new View.OnClickListener() { @Override public void onClick(View view) { @@ -118,8 +131,6 @@ public class PhotoPage extends Fragment { startActivity(intent); getActivity().finish(); } - - }; seeTutoButton.setOnClickListener(lSeeTutoButton); @@ -127,10 +138,18 @@ public class PhotoPage extends Fragment { return view; } + /** + * Handles the results from the camera or gallery activities. + * + * @param requestCode Code indicating the request type (camera or gallery). + * @param resultCode Result code from the activity. + * @param data Intent containing the result data. + */ @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); + // Handle result based on the request code if (data == null || resultCode != getActivity().RESULT_OK) { Log.e("PhotoPage", "Error: Data is null or result not OK"); return; @@ -166,16 +185,20 @@ public class PhotoPage extends Fragment { } } + /** + * Processes the given bitmap image for species recognition. + * + * @param bitmap The image to be processed. + */ private void processImage(Bitmap bitmap) { // Resize and/or preprocess the image for your recognition program Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, imageSize, imageSize, true); - // You can pass this `scaledBitmap` to your prediction program + // You can pass this scaledBitmap to your prediction program Log.d("PhotoPage", "Bitmap processed for prediction: " + scaledBitmap.toString()); - - try { + // Initialize the model and get predictions TestModeleTflite testModeleTflite = new TestModeleTflite(this.getContext()); outputPredictedImage = testModeleTflite.recognizeSpeciesClass(bitmap); Bitmap annotatedImage = outputPredictedImage.getAnnotatedImage(); @@ -183,7 +206,7 @@ public class PhotoPage extends Fragment { double width = 1.5 * annotatedImage.getWidth(); scaledBitmap = Bitmap.createScaledBitmap(annotatedImage, (int) width, (int) height, true); imageView.setImageBitmap(scaledBitmap); - predictionOutput=outputPredictedImage.toString(); + predictionOutput = outputPredictedImage.toString(); predictionResults = outputPredictedImage.getPredictionResults(); tableResultsLayout.setVisibility(View.VISIBLE); populateTable(); @@ -192,8 +215,7 @@ public class PhotoPage extends Fragment { } catch (NoSpeciesRecognizedException e) { tableResultsLayout.setVisibility(View.INVISIBLE); Toast.makeText(getContext(), "L'application n'a pas reconnu d'espèce connue sur votre photo.", Toast.LENGTH_LONG).show(); - predictionOutput="nothing"; - //textPredictionOutput.setText("Cette espèce n'est pas encore répertoriée."); + predictionOutput = "nothing"; } } @@ -220,6 +242,7 @@ public class PhotoPage extends Fragment { // Add the header row addHeaderRow(); + // Add data rows for each prediction result for (Map.Entry<String, RecognizeSpecie> entry : predictionResults.entrySet()) { TableRow dataRow = new TableRow(getContext()); @@ -240,41 +263,59 @@ public class PhotoPage extends Fragment { } } - /** * Adds a cell to a given table row. + * + * @param row The table row to which the cell will be added. + * @param text The text to display in the cell. */ private void addTableCell(TableRow row, String text) { TextView textView = new TextView(getContext()); textView.setText(text); textView.setPadding(16, 16, 16, 16); - textView.setTextColor(getResources().getColor(R.color.white)); // Optional: Add text styling row.addView(textView); } + /** + * Handles the results of a permission request, such as for camera access. + * + * @param requestCode Code indicating the request type. + * @param permissions Requested permissions. + * @param grantResults Results of the permission requests. + */ @RequiresApi(api = Build.VERSION_CODES.M) @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); + // Handle camera permission request results if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // Start the camera activity if permission is granted Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE); } else { + // Handle the case where permission is denied Log.e("PhotoPage", "Camera permission denied"); textPredictionOutput.setText("Camera permission denied. Please allow it to use this feature."); } } - } + /** + * Displays an overlay form for additional input. + */ public void showOverlayForm() { OverlayDialogFragmentForm overlayDialogForm = new OverlayDialogFragmentForm(); overlayDialogForm.show(getParentFragmentManager(), "overlayDialogForm"); } + /** + * Retrieves the prediction output string. + * + * @return The prediction output string. + */ public static String getPredictionOutput() { return predictionOutput; } diff --git a/app/src/main/java/com/example/myapplication/PublicActivity.java b/app/src/main/java/com/example/myapplication/PublicActivity.java index fe0336871e3cde8d7bd9a3befa5e7267f5acd643..ae8653ea3fe38b03820d5319dd1e19e57313812b 100644 --- a/app/src/main/java/com/example/myapplication/PublicActivity.java +++ b/app/src/main/java/com/example/myapplication/PublicActivity.java @@ -1,6 +1,5 @@ package com.example.myapplication; - import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; @@ -9,43 +8,60 @@ import android.os.Bundle; import com.google.android.material.bottomnavigation.BottomNavigationView; +/** + * PublicActivity represents an activity that hosts different fragments and provides navigation + * through a BottomNavigationView. It loads fragments based on the provided intent extra + * or the user's navigation choice. + */ public class PublicActivity extends AppCompatActivity { + + /** + * Called when the activity is created. This method initializes the UI, sets up the + * BottomNavigationView, and loads the correct fragment based on the "TARGET_FRAGMENT" + * provided in the intent or the user's navigation selection. + * + * @param savedInstanceState A bundle containing the saved state of the activity, + * or null if there was no previously saved state. + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_public); + // Initialize the BottomNavigationView BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation); - // Check for which fragment to load - String targetFragment=getIntent().getStringExtra("TARGET_FRAGMENT"); + // Get the target fragment name from the intent + String targetFragment = getIntent().getStringExtra("TARGET_FRAGMENT"); + + // Assert the fragment name is not null, then load the appropriate fragment assert targetFragment != null; switch (targetFragment) { case "LearningPage": - loadFragment(new LearningPage()); - bottomNavigationView.setSelectedItemId(R.id.navigation_apprendre); + loadFragment(new LearningPage()); // Load the LearningPage fragment + bottomNavigationView.setSelectedItemId(R.id.navigation_apprendre); // Select the appropriate bottom nav item break; case "StatsPage": - loadFragment(new StatsPage()); + loadFragment(new StatsPage()); // Load the StatsPage fragment bottomNavigationView.setSelectedItemId(R.id.navigation_statistiques); break; case "SettingsPage": + // Launch a new instance of PublicActivity to load the SettingsPage fragment Intent intent = new Intent(PublicActivity.this, PublicActivity.class); intent.putExtra("TARGET_FRAGMENT", "SettingsPage"); loadFragment(new SettingsPage()); bottomNavigationView.setSelectedItemId(R.id.navigation_parametres); break; case "PhotoPage": - loadFragment(new PhotoPage()); + loadFragment(new PhotoPage()); // Load the PhotoPage fragment bottomNavigationView.setSelectedItemId(R.id.navigation_identifier); break; } - // Set up navigation item selection - bottomNavigationView.setOnNavigationItemSelectedListener(item -> - - { + // Set up the BottomNavigationView item selection listener + bottomNavigationView.setOnNavigationItemSelectedListener(item -> { Fragment selectedFragment; + // Check the selected navigation item and load the corresponding fragment if (item.getItemId() == R.id.navigation_apprendre) { selectedFragment = new LearningPage(); } else if (item.getItemId() == R.id.navigation_statistiques) { @@ -55,21 +71,27 @@ public class PublicActivity extends AppCompatActivity { } else if (item.getItemId() == R.id.navigation_identifier) { selectedFragment = new PhotoPage(); } else { - selectedFragment=null; + // If none of the known items are selected, navigate back to HomeActivity + selectedFragment = null; Intent intent = new Intent(PublicActivity.this, HomeActivity.class); startActivity(intent); finish(); } - loadFragment(selectedFragment); + loadFragment(selectedFragment); // Load the selected fragment return true; }); } + /** + * Loads the specified fragment into the fragment container. + * + * @param fragment The fragment to load. + */ private void loadFragment(Fragment fragment) { + // Begin a fragment transaction to replace the current fragment with the new one getSupportFragmentManager() .beginTransaction() - .replace(R.id.fragment_container, fragment) - .commit(); + .replace(R.id.fragment_container, fragment) // Replace the current fragment + .commit(); // Commit the transaction } } - diff --git a/app/src/main/java/com/example/myapplication/ResultsFragment.java b/app/src/main/java/com/example/myapplication/ResultsFragment.java deleted file mode 100644 index 6822333db44192799ca58b8437354321978dfc87..0000000000000000000000000000000000000000 --- a/app/src/main/java/com/example/myapplication/ResultsFragment.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.example.myapplication; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import java.util.Map; - -public class ResultsFragment extends Fragment { - - private Map<String, RecognizeSpecie> predictionResults; - private Button backToPredictionButton; - - // Constructor to receive prediction results - public ResultsFragment(Map<String, RecognizeSpecie> predictionResults) { - this.predictionResults = predictionResults; - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_prediction_results, container, false); - - backToPredictionButton = view.findViewById(R.id.backToPrediction); - // Reference the TableLayout - TableLayout tableLayout = view.findViewById(R.id.results_table); - - // Add a header row to the table - addHeaderRow(tableLayout); - - // Populate the table with prediction results - populateTable(tableLayout); - - // Set up back button functionality - backToPredictionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - requireActivity() - .getSupportFragmentManager() - .popBackStack(); // Navigate back to the previous fragment - } - }); - - return view; - - - } - - /** - * Adds a header row to the table layout. - */ - private void addHeaderRow(TableLayout tableLayout) { - TableRow headerRow = new TableRow(getContext()); - headerRow.setBackgroundColor(getResources().getColor(R.color.myBlue)); // Optional: Add header styling - addTableCell(headerRow, "Espèce"); - addTableCell(headerRow, "Total individus"); - addTableCell(headerRow, "Précision(%)"); - tableLayout.addView(headerRow); - - } - - /** - * Populates the table with rows based on the prediction results. - */ - private void populateTable(TableLayout tableLayout) { - if (predictionResults != null) { - for (Map.Entry<String, RecognizeSpecie> entry : predictionResults.entrySet()) { - TableRow dataRow = new TableRow(getContext()); - - RecognizeSpecie specie = entry.getValue(); - - addTableCell(dataRow, entry.getKey()); // Species name - addTableCell(dataRow, String.valueOf(specie.getSpecieBoxes().size())); // Count - addTableCell(dataRow, String.format("%.2f", specie.getAverageProbability())); // Average probability - - tableLayout.addView(dataRow); - } - } else { - // If no data exists, add a message row - TableRow emptyRow = new TableRow(getContext()); - addTableCell(emptyRow, "No data available"); - tableLayout.addView(emptyRow); - } - } - - /** - * Adds a cell to a given table row. - */ - private void addTableCell(TableRow row, String text) { - TextView textView = new TextView(getContext()); - textView.setText(text); - textView.setPadding(16, 16, 16, 16); - - textView.setTextColor(getResources().getColor(R.color.white)); // Optional: Add text styling - row.addView(textView); - } -} diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentBecasseau.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBecasseau.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentBecasseau.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBecasseau.java index 43092ee17f22f621cc9827387e84ab273ad2dde7..a009906202061df0ebe7065838efe13a30257419 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentBecasseau.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBecasseau.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentBecasseau extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentBernache.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBernache.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentBernache.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBernache.java index e93978725d2fb0fbedce7a9aaa6b09561058d848..a1139487b22cf77cc751eafbf9ac376a6705d5f4 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentBernache.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentBernache.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentBernache extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentChevalier.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentChevalier.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentChevalier.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentChevalier.java index 09673ec52c06505f2061aa608f93d167918fa517..c412b7720ccff994957926c9d31a8c5da9b4f6cc 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentChevalier.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentChevalier.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentChevalier extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentCormoran.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentCormoran.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentCormoran.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentCormoran.java index 16bc12f0608f132706f908f485efd2d8feb37f6d..c5724c2c94ad8f55778df7da9168ec36805a203e 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentCormoran.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentCormoran.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentCormoran extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentForm.java similarity index 98% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentForm.java index 1194bf3dde8e58fd41c1236870f8cc624653de4c..c9141a6a193256582711bde3b7bb9ab32d582c9f 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentForm.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentForm.java @@ -1,7 +1,5 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; -import android.app.AlertDialog; -import android.content.DialogInterface; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -14,13 +12,16 @@ import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -import android.widget.TimePicker; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.GoogleFormApi; +import com.example.myapplication.PhotoPage; +import com.example.myapplication.R; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentFoulque.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentFoulque.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentFoulque.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentFoulque.java index 324ad8539cf333ba7a1d3cb278046bdb5cf3081c..1a12ad25cdb7ece0ef83b62f87756a8a0602b113 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentFoulque.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentFoulque.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentFoulque extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentGoeland.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentGoeland.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentGoeland.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentGoeland.java index ffc31366f988684c6acf9af72ed84f4c9a579e76..a0c7d91da2100b65f3cc7271a21cac0e0c40f6ca 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentGoeland.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentGoeland.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentGoeland extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentMouette.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentMouette.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentMouette.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentMouette.java index 47948e28e67e1d29d1efd65d0e156db30e49a8ae..862a71e693f6932ba1bc17c409df63788b8a4197 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentMouette.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentMouette.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentMouette extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentPluvier.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentPluvier.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentPluvier.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentPluvier.java index 7fab249a17260288785e28ea4d0c6acee16cc0bc..fa6a4ac6f8f1a73723ff1cef3ed09af1da3f8347 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentPluvier.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentPluvier.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentPluvier extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentTadorne.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentTadorne.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentTadorne.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentTadorne.java index 1ca876cb47d5b75d0271a8f8c3454c3f5b409562..371958f6161f4f2e237e20adf46b8053bdea8f22 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentTadorne.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentTadorne.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentTadorne extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentZonage.java similarity index 94% rename from app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java rename to app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentZonage.java index 0c3d5b0d8ae3ed1d50cb2e98d84ac4417659f832..b17dcaab9a229bc356ae015ca24ce6e8a4d651b6 100644 --- a/app/src/main/java/com/example/myapplication/OverlayDialogFragmentZonage.java +++ b/app/src/main/java/com/example/myapplication/overlays/OverlayDialogFragmentZonage.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.overlays; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +10,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; +import com.example.myapplication.R; + public class OverlayDialogFragmentZonage extends DialogFragment { @Nullable @Override diff --git a/app/src/main/java/com/example/myapplication/BoundingBox.java b/app/src/main/java/com/example/myapplication/recognation_logic/BoundingBox.java similarity index 92% rename from app/src/main/java/com/example/myapplication/BoundingBox.java rename to app/src/main/java/com/example/myapplication/recognation_logic/BoundingBox.java index 20110f1437f315d11d601bf1bcaa581080e56432..6396e59ef6fd39a1e1874654fce00e243c01444d 100644 --- a/app/src/main/java/com/example/myapplication/BoundingBox.java +++ b/app/src/main/java/com/example/myapplication/recognation_logic/BoundingBox.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.recognation_logic; public class BoundingBox { public float x1, y1, x2, y2, cx, cy, w, h, cnf; diff --git a/app/src/main/java/com/example/myapplication/NoSpeciesRecognizedException.java b/app/src/main/java/com/example/myapplication/recognation_logic/NoSpeciesRecognizedException.java similarity index 55% rename from app/src/main/java/com/example/myapplication/NoSpeciesRecognizedException.java rename to app/src/main/java/com/example/myapplication/recognation_logic/NoSpeciesRecognizedException.java index a23697cd73f2b89794485f176c7dc6b9609d55b2..fd5f1dfd8333203d0b06f09645e31900a51564e5 100644 --- a/app/src/main/java/com/example/myapplication/NoSpeciesRecognizedException.java +++ b/app/src/main/java/com/example/myapplication/recognation_logic/NoSpeciesRecognizedException.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.recognation_logic; public class NoSpeciesRecognizedException extends Exception{ diff --git a/app/src/main/java/com/example/myapplication/OutputPredictedImage.java b/app/src/main/java/com/example/myapplication/recognation_logic/OutputPredictedImage.java similarity index 92% rename from app/src/main/java/com/example/myapplication/OutputPredictedImage.java rename to app/src/main/java/com/example/myapplication/recognation_logic/OutputPredictedImage.java index 97423b88048b43858d4878b3920961c71ae723e3..2f4e005759f9a6095aaf39f2973819af7aea4200 100644 --- a/app/src/main/java/com/example/myapplication/OutputPredictedImage.java +++ b/app/src/main/java/com/example/myapplication/recognation_logic/OutputPredictedImage.java @@ -1,9 +1,7 @@ -package com.example.myapplication; +package com.example.myapplication.recognation_logic; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import java.util.List; import java.util.Map; /** diff --git a/app/src/main/java/com/example/myapplication/RecognizeSpecie.java b/app/src/main/java/com/example/myapplication/recognation_logic/RecognizeSpecie.java similarity index 95% rename from app/src/main/java/com/example/myapplication/RecognizeSpecie.java rename to app/src/main/java/com/example/myapplication/recognation_logic/RecognizeSpecie.java index 43ae2525a9ad5d20e7e3a5bd083d5ffe7fa9c6ca..de3f52a9c95700677f246ce6a597d66cb67057f7 100644 --- a/app/src/main/java/com/example/myapplication/RecognizeSpecie.java +++ b/app/src/main/java/com/example/myapplication/recognation_logic/RecognizeSpecie.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.recognation_logic; import java.io.Serializable; import java.util.List; diff --git a/app/src/main/java/com/example/myapplication/TestModeleTflite.java b/app/src/main/java/com/example/myapplication/recognation_logic/TestModeleTflite.java similarity index 89% rename from app/src/main/java/com/example/myapplication/TestModeleTflite.java rename to app/src/main/java/com/example/myapplication/recognation_logic/TestModeleTflite.java index 6b10aca6468ce576a4a7356e7a5773b570729f68..3f0a504bd47ceaf96928d35cc77785aa89146bbf 100644 --- a/app/src/main/java/com/example/myapplication/TestModeleTflite.java +++ b/app/src/main/java/com/example/myapplication/recognation_logic/TestModeleTflite.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.recognation_logic; import static android.graphics.Paint.*; @@ -40,7 +40,7 @@ public class TestModeleTflite { private static final float INPUT_STANDARD_DEVIATION = 255f; private static final DataType INPUT_IMAGE_TYPE = DataType.FLOAT32; private static final DataType OUTPUT_IMAGE_TYPE = DataType.FLOAT32; - private static final float CONFIDENCE_THRESHOLD = 0.3F; + private static final float CONFIDENCE_THRESHOLD = 0.4F; private static final float IOU_THRESHOLD = 0.5F; private Interpreter interpreter; @@ -144,20 +144,24 @@ public class TestModeleTflite { */ public OutputPredictedImage recognizeSpeciesClass(Bitmap inputImage) throws NoSpeciesRecognizedException { Map<String, RecognizeSpecie> predictionResults = new HashMap<>(); + TensorBuffer outputBuffer = predict(inputImage); List<BoundingBox> boxes = processOutput(outputBuffer); - - if (boxes != null) { - System.out.println("not empty"); + if (boxes != null && !boxes.isEmpty()) { for (BoundingBox box : boxes) { - predictionResults.computeIfAbsent(box.clsName, k -> new RecognizeSpecie(k, new ArrayList<>())) - .getSpecieBoxes().add(box); + if (predictionResults.containsKey(box.clsName)) { + predictionResults.get(box.clsName).getSpecieBoxes().add(box); + } else { + predictionResults.put(box.clsName, new RecognizeSpecie(box.clsName, new ArrayList<>())); + predictionResults.get(box.clsName).getSpecieBoxes().add(box); + } } Bitmap annotatedImage = annotateImage(inputImage, boxes); return new OutputPredictedImage(annotatedImage, predictionResults); } else { throw new NoSpeciesRecognizedException(); } + } /** @@ -248,35 +252,6 @@ public class TestModeleTflite { /** * Draws bounding boxes on an image. */ - /* - private Bitmap drawBoundingBoxes(Bitmap bitmap, List<BoundingBox> boxes) { - Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); - Canvas canvas = new Canvas(mutableBitmap); - - Paint paint = new Paint(); - paint.setColor(Color.RED); - paint.setStyle(Style.STROKE); - paint.setStrokeWidth(8f); - /* - Paint textPaint = new Paint(); - textPaint.setColor(Color.WHITE); - textPaint.setTextSize(40f); - //textPaint.setTypeface(Paint.DEFAULT_BOLD); - - for (BoundingBox box : boxes) { - RectF rect = new RectF( - box.x1 * mutableBitmap.getWidth(), - box.y1 * mutableBitmap.getHeight(), - box.x2 * mutableBitmap.getWidth(), - box.y2 * mutableBitmap.getHeight() - ); - canvas.drawRect(rect, paint); - //canvas.drawText(box.clsName, rect.left, rect.bottom, textPaint); - } - - return mutableBitmap; - }*/ - private Bitmap drawBoundingBoxes(Bitmap bitmap, List<BoundingBox> boxes) { Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); Canvas canvas = new Canvas(mutableBitmap); diff --git a/app/src/main/java/com/example/myapplication/TutorialActivity.java b/app/src/main/java/com/example/myapplication/tutorials/TutorialActivity.java similarity index 95% rename from app/src/main/java/com/example/myapplication/TutorialActivity.java rename to app/src/main/java/com/example/myapplication/tutorials/TutorialActivity.java index 9749d0026ec28f764835c03ab945d1071d485d4f..5605f67d41c8273449049df7e6301f8bc1f455cd 100644 --- a/app/src/main/java/com/example/myapplication/TutorialActivity.java +++ b/app/src/main/java/com/example/myapplication/tutorials/TutorialActivity.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.tutorials; import android.content.Intent; import android.os.Bundle; @@ -11,6 +11,9 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import androidx.viewpager2.widget.ViewPager2; +import com.example.myapplication.HomeActivity; +import com.example.myapplication.R; + import java.util.Arrays; import java.util.List; diff --git a/app/src/main/java/com/example/myapplication/TutorialFragmentAdapter.java b/app/src/main/java/com/example/myapplication/tutorials/TutorialFragmentAdapter.java similarity index 94% rename from app/src/main/java/com/example/myapplication/TutorialFragmentAdapter.java rename to app/src/main/java/com/example/myapplication/tutorials/TutorialFragmentAdapter.java index 1deec3b60cf50807ef9c57a7af0f5620bce3e79b..de09261ac8a7f27181e649432f9795a97fbfa8f7 100644 --- a/app/src/main/java/com/example/myapplication/TutorialFragmentAdapter.java +++ b/app/src/main/java/com/example/myapplication/tutorials/TutorialFragmentAdapter.java @@ -1,4 +1,4 @@ -package com.example.myapplication; +package com.example.myapplication.tutorials; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; diff --git a/app/src/main/java/com/example/myapplication/TutorialPageFragment.java b/app/src/main/java/com/example/myapplication/tutorials/TutorialPageFragment.java similarity index 93% rename from app/src/main/java/com/example/myapplication/TutorialPageFragment.java rename to app/src/main/java/com/example/myapplication/tutorials/TutorialPageFragment.java index 803cea3530f0dd9caa401dd308558164ef06744d..89ff29c5885ef7168d1fe688c57ff8d3e5148fdc 100644 --- a/app/src/main/java/com/example/myapplication/TutorialPageFragment.java +++ b/app/src/main/java/com/example/myapplication/tutorials/TutorialPageFragment.java @@ -1,10 +1,9 @@ -package com.example.myapplication; +package com.example.myapplication.tutorials; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/res/layout/activity_tutorial.xml b/app/src/main/res/layout/activity_tutorial.xml index 4f6b328cb67b42118e3df396511285f24f9e1bea..ecb37940b454bc0c8158f93bd00157c90a66b2e7 100644 --- a/app/src/main/res/layout/activity_tutorial.xml +++ b/app/src/main/res/layout/activity_tutorial.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/black" - tools:context=".TutorialActivity"> + tools:context=".tutorials.TutorialActivity"> <ImageView android:id="@+id/image_1"