diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000000000000000000000000000000000000..bcc86d028b8926c046232de093542c8531d29daf --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="deploymentTargetSelector"> + <selectionStates> + <SelectionState runConfigName="app"> + <option name="selectionMode" value="DROPDOWN" /> + <DropdownSelection timestamp="2025-01-04T02:38:58.283128700Z"> + <Target type="DEFAULT_BOOT"> + <handle> + <DeviceId pluginId="PhysicalDevice" identifier="serial=R39M30F5B2T" /> + </handle> + </Target> + </DropdownSelection> + <DialogSelection /> + </SelectionState> + </selectionStates> + </component> +</project> \ No newline at end of file diff --git a/app/src/main/java/com/example/myapplication/PhotoPage.java b/app/src/main/java/com/example/myapplication/PhotoPage.java index bd727d5715018934a93a952387b4e2e642c1cd37..7dea134080e4ef2a9f51ce4ad17bf18ddf2ec369 100644 --- a/app/src/main/java/com/example/myapplication/PhotoPage.java +++ b/app/src/main/java/com/example/myapplication/PhotoPage.java @@ -25,10 +25,13 @@ 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; import android.widget.Toast; import java.io.IOException; +import java.util.Map; public class PhotoPage extends Fragment { private static final int CAMERA_REQUEST_CODE = 3; @@ -41,7 +44,10 @@ public class PhotoPage extends Fragment { TextView textPredictionOutput, textProbabilityOutput; ImageView imageView; FrameLayout formLayout; + FrameLayout tableResultsLayout; OutputPredictedImage outputPredictedImage; + private Map<String, RecognizeSpecie> predictionResults; + TableLayout tablePredictionResults; int imageSize = 256; @@ -55,8 +61,9 @@ public class PhotoPage extends Fragment { cameraButton = view.findViewById(R.id.camera_button); folderButton = view.findViewById(R.id.folder_button); identifiedSpeciesButton = view.findViewById(R.id.identified_species_button); - textPredictionOutput = view.findViewById(R.id.textPredictionOutput); - //textProbabilityOutput = view.findViewById(R.id.textProbabilityOutput); + tablePredictionResults = view.findViewById(R.id.results_table1); + tableResultsLayout = view.findViewById(R.id.tableResultsLayout); + tableResultsLayout.setVisibility(View.INVISIBLE); imageView = view.findViewById(R.id.main_image_display); Button seeTutoButton = view.findViewById(R.id.see_tuto); @@ -85,6 +92,7 @@ public class PhotoPage extends Fragment { } }); + /* identifiedSpeciesButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -101,7 +109,7 @@ public class PhotoPage extends Fragment { } } - }); + });*/ View.OnClickListener lSeeTutoButton = new View.OnClickListener() { @Override public void onClick(View view) { @@ -165,6 +173,8 @@ public class PhotoPage extends Fragment { // You can pass this `scaledBitmap` to your prediction program Log.d("PhotoPage", "Bitmap processed for prediction: " + scaledBitmap.toString()); + + try { TestModeleTflite testModeleTflite = new TestModeleTflite(this.getContext()); outputPredictedImage = testModeleTflite.recognizeSpeciesClass(bitmap); @@ -173,18 +183,76 @@ public class PhotoPage extends Fragment { double width = 1.5 * annotatedImage.getWidth(); scaledBitmap = Bitmap.createScaledBitmap(annotatedImage, (int) width, (int) height, true); imageView.setImageBitmap(scaledBitmap); - //TextView textView = getView().findViewById(R.id.textView2); predictionOutput=outputPredictedImage.toString(); - textPredictionOutput.setText(outputPredictedImage.toString()); + predictionResults = outputPredictedImage.getPredictionResults(); + tableResultsLayout.setVisibility(View.VISIBLE); + populateTable(); } catch (IOException e) { throw new RuntimeException(e); } catch (NoSpeciesRecognizedException e) { - Toast.makeText(getContext(), "L'application n'a pas reconnu d'espèce connue sur votre photo", Toast.LENGTH_SHORT).show(); + 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."); + //textPredictionOutput.setText("Cette espèce n'est pas encore répertoriée."); + } + } + + /** + * Adds a header row to the table layout. + */ + private void addHeaderRow() { + 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(%)"); + tablePredictionResults.addView(headerRow); + } + + /** + * Populates the table with rows based on the prediction results. + */ + private void populateTable() { + if (predictionResults != null) { + // Clear the table to remove any previous rows + tablePredictionResults.removeAllViews(); + + // Add the header row + addHeaderRow(); + + 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 + + tablePredictionResults.addView(dataRow); + } + } else { + // If no data exists, clear and add a message row + tablePredictionResults.removeAllViews(); // Clear existing rows + TableRow emptyRow = new TableRow(getContext()); + addTableCell(emptyRow, "No data available"); + tablePredictionResults.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); + } + @RequiresApi(api = Build.VERSION_CODES.M) @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { diff --git a/app/src/main/java/com/example/myapplication/ResultsFragment.java b/app/src/main/java/com/example/myapplication/ResultsFragment.java index 866329cb2700756fcb84eb3b6b57f83e8295fcbd..6822333db44192799ca58b8437354321978dfc87 100644 --- a/app/src/main/java/com/example/myapplication/ResultsFragment.java +++ b/app/src/main/java/com/example/myapplication/ResultsFragment.java @@ -4,6 +4,7 @@ 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; @@ -17,6 +18,7 @@ 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) { @@ -29,6 +31,7 @@ public class ResultsFragment extends Fragment { // 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); @@ -38,7 +41,19 @@ public class ResultsFragment extends Fragment { // 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; + + } /** @@ -46,11 +61,12 @@ public class ResultsFragment extends Fragment { */ private void addHeaderRow(TableLayout tableLayout) { TableRow headerRow = new TableRow(getContext()); - headerRow.setBackgroundColor(getResources().getColor(R.color.logo2_background)); // Optional: Add header styling + 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); + } /** diff --git a/app/src/main/res/layout/fragment_photo_page.xml b/app/src/main/res/layout/fragment_photo_page.xml index a6148b99adaf2cb3b1f73b9347bc99d4537c5479..903b689287fa33b6c2dd9c52a693b54be9262236 100644 --- a/app/src/main/res/layout/fragment_photo_page.xml +++ b/app/src/main/res/layout/fragment_photo_page.xml @@ -73,7 +73,7 @@ android:layout_marginTop="20dp" android:fontFamily="@font/inter" android:paddingHorizontal="40dp" - android:text="Voir espèce(s) identifiée(s)" + android:text="Espèce(s) identifiée(s)" android:textSize="15sp" /> </FrameLayout> @@ -85,43 +85,46 @@ <TextView - android:id="@+id/textPredictionOutput" - android:layout_width="351dp" - android:layout_height="28dp" - android:layout_gravity="bottom|center_horizontal" - android:layout_marginBottom="146dp" - android:text="" - android:textColor="#F12B2B" - android:textSize="17sp" - android:textStyle="bold" /> - - - <TextView - android:id="@+id/prediction_label" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center_horizontal|bottom" - android:layout_marginBottom="186dp" - android:text="PREDICTION:" - android:textColor="#D9D9D9" - android:textSize="24sp" - android:textStyle="bold" /> - - <TextView - style="@style/PageTitleAppearance" android:id="@+id/learning_page_title" + style="@style/PageTitleAppearance" android:layout_marginTop="50dp" android:layout_marginBottom="60dp" android:paddingTop="30dp" android:paddingEnd="50dp" android:text="@string/photo" /> - <EditText - android:id="@+id/editTextTextMultiLine4" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ems="10" - android:gravity="start|top" - android:inputType="textMultiLine" /> + + <FrameLayout + style="@style/TopTopAppearance" + android:id="@+id/tableResultsLayout" + android:layout_width="362dp" + android:layout_height="90dp" + android:layout_gravity="center_horizontal|bottom" + android:layout_marginBottom="110dp"> + + <ScrollView + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="7dp"> + + <TableLayout + android:id="@+id/results_table1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:stretchColumns="1"> + <!-- Rows will be added dynamically --> + </TableLayout> + + </LinearLayout> + </ScrollView> + + </FrameLayout> + + </FrameLayout> diff --git a/app/src/main/res/layout/fragment_prediction_results.xml b/app/src/main/res/layout/fragment_prediction_results.xml index ac35b198d3d3b84a3db9ee681a638cdc9a04f00e..ad2ed74fde99dbb0b992d321d5b77d88fab20b3f 100644 --- a/app/src/main/res/layout/fragment_prediction_results.xml +++ b/app/src/main/res/layout/fragment_prediction_results.xml @@ -10,7 +10,7 @@ <FrameLayout style="@style/TopTopAppearance" android:layout_width="362dp" - android:layout_height="93dp" + android:layout_height="120dp" android:layout_gravity="center"> <ScrollView @@ -37,6 +37,30 @@ </FrameLayout> + <TextView + android:id="@+id/prediction_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal|top" + android:layout_marginTop="320dp" + android:text="Détails de la Prédiction:" + android:textColor="#D9D9D9" + android:textSize="30sp" + android:textStyle="bold" /> + + <Button + android:id="@+id/backToPrediction" + style="@style/ButtonAppearance" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_marginBottom="300dp" + android:fontFamily="@font/inter" + android:text="Retour" + android:textSize="20sp" /> + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index c8524cd961d27b6695e755c6ef2d4d58cf38431e..edd55aba2128f737aefd9a04083f85d52e3cc49a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -2,4 +2,5 @@ <resources> <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> + <color name="myBlue">#517293</color> </resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1272c73827e38d8321de1f6783c7fd67d9833af6..8f813d0a20d69b4b665b6c90371e2661f308af20 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,7 +82,7 @@ <string name="mode_sombre_texte">Le mode sombre économise votre batterie et lutte contre la fatigue visuelle</string> <string name="download_text">Télécharge un guide d’utilisation approfondi de l’application au format pdf</string> <string name="photo_time_text">Confirmez l\'heure de la prise de la photo</string> - <string name="locate_text">Localisation (qu\'est ce que vous voyez?)</string> + <string name="locate_text">Localisation (qu\'est ce que vous voyez autour de vous? ex: un arbre, un rocher, autre?)</string> <string name="send">Envoyer</string> <string name="desc_text">Que voyez-vous autour de vous ?</string> <string name="zone_info_text">Plus d\'info sur les zones</string>