GeorgeIbrahim commited on
Commit
8be8093
·
1 Parent(s): 52084ff
Files changed (1) hide show
  1. app.py +60 -62
app.py CHANGED
@@ -13,103 +13,94 @@ if token:
13
  login(token=token)
14
  else:
15
  print("HUGGINGFACE_TOKEN environment variable not set.")
16
-
17
  dataset_name = "GeorgeIbrahim/EGYCOCO" # Replace with your dataset name
18
 
19
- # Load or create the dataset with a new 'split' column
20
  try:
21
  dataset = load_dataset(dataset_name, split="train")
22
  print("Loaded existing dataset:", dataset)
23
 
24
- # Load the nearest neighbors JSON file
25
- with open('nearest_neighbors_with_captions.json', 'r') as f:
26
- results = json.load(f)
 
 
 
 
27
 
28
- # Define the new features with the added 'split' column
 
 
 
29
  features = Features({
30
  'image_id': Value(dtype='string'),
31
  'caption': Value(dtype='string'),
32
- 'annotation_count': Value(dtype='int32'),
33
- 'split': Value(dtype='string') # New 'split' column
34
  })
35
-
36
- # Populate the 'split' column based on whether image_id is in results
37
- updated_data = {
38
- 'image_id': [],
39
- 'caption': [],
40
- 'annotation_count': [],
41
- 'split': []
42
- }
43
-
44
- for example in dataset:
45
- image_id = example["image_id"]
46
- updated_data['image_id'].append(image_id)
47
- updated_data['caption'].append(example["caption"])
48
- updated_data['annotation_count'].append(example["annotation_count"])
49
- # Determine the split type based on whether it's in the validation set
50
- split_type = "dev" if image_id in results else "train"
51
- updated_data['split'].append(split_type)
52
-
53
- # Create a new dataset with updated features and push to the hub
54
- updated_dataset = Dataset.from_dict(updated_data, features=features)
55
- updated_dataset.push_to_hub(dataset_name)
56
- print("Dataset updated with 'split' column and pushed to Hugging Face.")
57
-
58
- except Exception as e:
59
- print(f"Error loading or updating dataset: {e}")
60
 
61
  image_folder = "images"
62
  image_files = [f for f in os.listdir(image_folder) if f.endswith(('.png', '.jpg', '.jpeg'))]
63
  lock = threading.Lock()
64
 
65
- # Initialize annotation counts
66
- annotation_counts = {}
67
- for example in dataset:
68
- image_id = example["image_id"]
69
- count = example["annotation_count"]
70
- annotation_counts[image_id] = count
71
 
72
  def get_caption_for_image_id(image_path):
73
  """
74
  Retrieve the caption for a given image_id from the JSON data.
75
  """
 
76
  match = re.search(r'_(\d+)\.', image_path)
77
  if match:
78
- image_id = match.group(1).lstrip('0')
79
- print("Searching for image_id:", image_id)
80
 
 
81
  if image_id in results:
82
- print("Found caption in results:", results[image_id]["caption"])
83
  return results[image_id]["caption"]
84
 
 
85
  for test_image_data in results.values():
86
  for neighbor in test_image_data["nearest_neighbors"]:
87
  if neighbor["image_id"] == image_id:
88
- print("Found caption in nearest neighbors:", neighbor["caption"])
89
  return neighbor["caption"]
90
 
91
- print("Caption not found for image_id:", image_id)
 
92
  return None
93
 
 
94
  # Function to get a random image that hasn’t been fully annotated
95
  def get_next_image(session_data):
96
  with lock:
 
97
  available_images = [
98
  img for img in image_files
99
- if img not in annotation_counts or annotation_counts.get(img, 0) < (2 if img in results else 1)
 
 
100
  ]
101
 
102
- print("Available images:", available_images)
103
 
 
104
  if session_data["current_image"] is None and available_images:
 
105
  session_data["current_image"] = random.choice(available_images)
106
- print("Current image_id:", session_data["current_image"])
107
 
108
  return os.path.join(image_folder, session_data["current_image"]) if session_data["current_image"] else None
109
 
 
110
  # Function to save the annotation to Hugging Face dataset and fetch the next image
111
  def save_annotation(caption, session_data):
112
- global dataset, annotation_counts
113
 
114
  if session_data["current_image"] is None:
115
  return gr.update(visible=False), gr.update(value="All images have been annotated!"), gr.update(value="")
@@ -117,66 +108,73 @@ def save_annotation(caption, session_data):
117
  with lock:
118
  image_id = session_data["current_image"]
119
 
 
120
  if caption.strip().lower() == "skip":
121
  caption = "skipped"
122
 
 
123
  annotation_count = annotation_counts.get(image_id, 0)
124
 
125
- # Determine the split type based on whether it's in the validation set
126
- split_type = "dev" if image_id in results else "train"
127
-
128
  new_data = Dataset.from_dict({
129
  "image_id": [image_id],
130
  "caption": [caption],
131
- "annotation_count": [annotation_count + 1],
132
- "split": [split_type]
133
  }, features=Features({
134
  'image_id': Value(dtype='string'),
135
  'caption': Value(dtype='string'),
136
- 'annotation_count': Value(dtype='int32'),
137
- 'split': Value(dtype='string')
138
  }))
139
 
 
140
  annotation_counts[image_id] = annotation_count + 1
141
 
 
142
  dataset = concatenate_datasets([dataset, new_data])
143
  dataset.push_to_hub(dataset_name)
144
  print("Pushed updated dataset")
145
 
146
- if annotation_counts[image_id] >= (2 if image_id in results else 1):
 
147
  session_data["current_image"] = None
148
 
 
149
  next_image = get_next_image(session_data)
150
  if next_image:
151
- next_caption = get_caption_for_image_id(os.path.basename(next_image))
152
- print("Next image_id:", os.path.basename(next_image))
153
  return gr.update(value=next_image), gr.update(value=""), gr.update(value=next_caption or "")
154
  else:
155
  return gr.update(visible=False), gr.update(value="All images have been annotated!"), gr.update(value="")
156
 
 
157
  def initialize_interface(session_data):
158
  next_image = get_next_image(session_data)
159
  if next_image:
160
- next_caption = get_caption_for_image_id(os.path.basename(next_image))
161
- print("Initial image_id:", os.path.basename(next_image))
162
  return gr.update(value=next_image), gr.update(value=next_caption or "")
163
  else:
164
  return gr.update(visible=False), gr.update(value="All images have been annotated!")
165
 
 
 
166
  with gr.Blocks() as demo:
167
  gr.Markdown("# Image Captioning Tool")
168
  gr.Markdown("Please provide your caption in Egyptian Arabic 'Masri'")
169
 
170
- session_data = gr.State({"current_image": None})
171
 
172
  with gr.Row():
173
  image = gr.Image()
174
  caption = gr.Textbox(placeholder="Enter caption here...")
175
- existing_caption = gr.Textbox(label="Existing Caption", interactive=False)
176
  submit = gr.Button("Submit")
177
 
 
178
  submit.click(fn=save_annotation, inputs=[caption, session_data], outputs=[image, caption, existing_caption])
179
 
 
180
  demo.load(fn=initialize_interface, inputs=session_data, outputs=[image, existing_caption])
181
 
182
  demo.launch(share=True)
 
13
  login(token=token)
14
  else:
15
  print("HUGGINGFACE_TOKEN environment variable not set.")
 
16
  dataset_name = "GeorgeIbrahim/EGYCOCO" # Replace with your dataset name
17
 
18
+ # Load or create the dataset
19
  try:
20
  dataset = load_dataset(dataset_name, split="train")
21
  print("Loaded existing dataset:", dataset)
22
 
23
+ # Create a dictionary to keep track of the highest annotation count for each image
24
+ annotation_counts = {}
25
+ for example in dataset:
26
+ image_id = example["image_id"]
27
+ count = example["annotation_count"]
28
+ if image_id not in annotation_counts or count > annotation_counts[image_id]:
29
+ annotation_counts[image_id] = count
30
 
31
+ print("Annotation counts:", annotation_counts)
32
+ except Exception as e:
33
+ print(f"Error loading dataset: {e}")
34
+ # Create an empty dataset if it doesn't exist
35
  features = Features({
36
  'image_id': Value(dtype='string'),
37
  'caption': Value(dtype='string'),
38
+ 'annotation_count': Value(dtype='int32') # Add annotation count feature
 
39
  })
40
+ dataset = Dataset.from_dict({'image_id': [], 'caption': [], 'annotation_count': []}, features=features)
41
+ annotation_counts = {}
42
+ dataset.push_to_hub(dataset_name) # Push the empty dataset to Hugging Face
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  image_folder = "images"
45
  image_files = [f for f in os.listdir(image_folder) if f.endswith(('.png', '.jpg', '.jpeg'))]
46
  lock = threading.Lock()
47
 
48
+ with open('nearest_neighbors_with_captions.json', 'r') as f:
49
+ results = json.load(f)
50
+
 
 
 
51
 
52
  def get_caption_for_image_id(image_path):
53
  """
54
  Retrieve the caption for a given image_id from the JSON data.
55
  """
56
+ # Extract the numeric part of the image ID
57
  match = re.search(r'_(\d+)\.', image_path)
58
  if match:
59
+ image_id = match.group(1).lstrip('0') # Remove leading zeros
60
+ print("Searching for image_id:", image_id) # Debugging line
61
 
62
+ # Check if image_id is a test image
63
  if image_id in results:
64
+ print("Found caption in results:", results[image_id]["caption"]) # Debugging line
65
  return results[image_id]["caption"]
66
 
67
+ # If image_id is not a test image, search in nearest neighbors
68
  for test_image_data in results.values():
69
  for neighbor in test_image_data["nearest_neighbors"]:
70
  if neighbor["image_id"] == image_id:
71
+ print("Found caption in nearest neighbors:", neighbor["caption"]) # Debugging line
72
  return neighbor["caption"]
73
 
74
+ # Return None if the image_id is not found
75
+ print("Caption not found for image_id:", image_id) # Debugging line
76
  return None
77
 
78
+
79
  # Function to get a random image that hasn’t been fully annotated
80
  def get_next_image(session_data):
81
  with lock:
82
+ # Available images filter
83
  available_images = [
84
  img for img in image_files
85
+ if img not in annotation_counts or
86
+ ("val" in img and annotation_counts.get(img, 0) < 2) or
87
+ ("val" not in img and annotation_counts.get(img, 0) == 0)
88
  ]
89
 
90
+ print("Available images:", available_images) # Debugging line
91
 
92
+ # Check if the user already has an image
93
  if session_data["current_image"] is None and available_images:
94
+ # Assign a new random image to the user
95
  session_data["current_image"] = random.choice(available_images)
96
+ print("Current image_id:", session_data["current_image"]) # Print the current image_id
97
 
98
  return os.path.join(image_folder, session_data["current_image"]) if session_data["current_image"] else None
99
 
100
+
101
  # Function to save the annotation to Hugging Face dataset and fetch the next image
102
  def save_annotation(caption, session_data):
103
+ global dataset, annotation_counts # Declare global dataset and annotation_counts at the start of the function
104
 
105
  if session_data["current_image"] is None:
106
  return gr.update(visible=False), gr.update(value="All images have been annotated!"), gr.update(value="")
 
108
  with lock:
109
  image_id = session_data["current_image"]
110
 
111
+ # Save caption or "skipped" based on user input
112
  if caption.strip().lower() == "skip":
113
  caption = "skipped"
114
 
115
+ # Get current annotation count
116
  annotation_count = annotation_counts.get(image_id, 0)
117
 
118
+ # Add the new annotation as a new row to the dataset
 
 
119
  new_data = Dataset.from_dict({
120
  "image_id": [image_id],
121
  "caption": [caption],
122
+ "annotation_count": [annotation_count + 1] # Increment the annotation count
 
123
  }, features=Features({
124
  'image_id': Value(dtype='string'),
125
  'caption': Value(dtype='string'),
126
+ 'annotation_count': Value(dtype='int32') # Ensure int32 type
 
127
  }))
128
 
129
+ # Update the annotation count in the dictionary
130
  annotation_counts[image_id] = annotation_count + 1
131
 
132
+ # Concatenate with the existing dataset and push the updated dataset to Hugging Face
133
  dataset = concatenate_datasets([dataset, new_data])
134
  dataset.push_to_hub(dataset_name)
135
  print("Pushed updated dataset")
136
 
137
+ # Clear user's current image if the validation image has been annotated twice
138
+ if ("val" not in image_id) or (annotation_count + 1 >= 2):
139
  session_data["current_image"] = None
140
 
141
+ # Fetch the next image
142
  next_image = get_next_image(session_data)
143
  if next_image:
144
+ next_caption = get_caption_for_image_id(os.path.basename(next_image)) # Retrieve the caption for the new image
145
+ print("Next image_id:", os.path.basename(next_image)) # Debugging line
146
  return gr.update(value=next_image), gr.update(value=""), gr.update(value=next_caption or "")
147
  else:
148
  return gr.update(visible=False), gr.update(value="All images have been annotated!"), gr.update(value="")
149
 
150
+
151
  def initialize_interface(session_data):
152
  next_image = get_next_image(session_data)
153
  if next_image:
154
+ next_caption = get_caption_for_image_id(os.path.basename(next_image)) # Retrieve caption for initial image
155
+ print("Initial image_id:", os.path.basename(next_image)) # Print the initial image_id
156
  return gr.update(value=next_image), gr.update(value=next_caption or "")
157
  else:
158
  return gr.update(visible=False), gr.update(value="All images have been annotated!")
159
 
160
+
161
+ # Build the Gradio interface
162
  with gr.Blocks() as demo:
163
  gr.Markdown("# Image Captioning Tool")
164
  gr.Markdown("Please provide your caption in Egyptian Arabic 'Masri'")
165
 
166
+ session_data = gr.State({"current_image": None}) # Session-specific state
167
 
168
  with gr.Row():
169
  image = gr.Image()
170
  caption = gr.Textbox(placeholder="Enter caption here...")
171
+ existing_caption = gr.Textbox(label="Existing Caption", interactive=False) # Display existing caption
172
  submit = gr.Button("Submit")
173
 
174
+ # Define actions for buttons
175
  submit.click(fn=save_annotation, inputs=[caption, session_data], outputs=[image, caption, existing_caption])
176
 
177
+ # Load initial image
178
  demo.load(fn=initialize_interface, inputs=session_data, outputs=[image, existing_caption])
179
 
180
  demo.launch(share=True)