gdms commited on
Commit
eebb83e
·
1 Parent(s): 4c13cc7

Pergunta Chess ok!!!

Browse files
image_analysis_output/analysis_results.json CHANGED
@@ -1,6 +1,7 @@
1
  [
2
  {
3
  "image": "arquivos-perguntas/cca530fc-4052-43b2-b130-b30968d8aa44.png",
4
- "analysis": "3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1_b_-_-_0_1"
 
5
  }
6
  ]
 
1
  [
2
  {
3
  "image": "arquivos-perguntas/cca530fc-4052-43b2-b130-b30968d8aa44.png",
4
+ "fen": "3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1 b - - 0 1",
5
+ "move": "Rd5"
6
  }
7
  ]
tool_image_llm_template.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Script para baixar um vídeo do YouTube, extrair frames, analisar com GPT-4o e contar aves.
4
+ """
5
+
6
+ import os
7
+ import subprocess
8
+ import cv2
9
+ import base64
10
+ import time
11
+ from openai import OpenAI # Importa a classe OpenAI
12
+ import json
13
+ import re
14
+ import shutil
15
+
16
+ import google.generativeai as genai
17
+ import requests
18
+
19
+
20
+ # --- Configurações (Substitua os placeholders) ---
21
+ OUTPUT_DIR = "./image_analysis_output" # Diretório para salvar o vídeo e os frames
22
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
23
+ GEMINI_MODEL = "gemini-2.0-flash"
24
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
25
+ GPT_MODEL = "gpt-4o" # Modelo GPT a ser usado (certifique-se que é o correto para análise de imagem)
26
+ PROMPT_TEXT = "Analyze the provided image of a chessboard, return the corresponding FEN (Forsyth–Edwards Notation), assuming black at the bottom and black turn. Include turn, castling rights, en passant (if possible), and full notation. Return only the FEN."
27
+ #PROMPT_TEXT = "You are a chessboard position analyzer. Given an image of a chessboard: - Assume standard orientation: White at the bottom, Black at the top. - Identify all visible pieces and their positions. - Return the FEN string corresponding to the exact position. - Be precise. Do not omit or infer captured pieces. - Return only the FEN, no explanations."
28
+ IMAGE_FILE = "arquivos-perguntas/cca530fc-4052-43b2-b130-b30968d8aa44.png"
29
+ RESULTS_FILE = os.path.join(OUTPUT_DIR, "analysis_results.json")
30
+ FEN_CORRETA = "3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1 b - - 0 1"
31
+ CHESSVISION_TO_FEN_URL = "http://app.chessvision.ai/predict"
32
+ CHESS_MOVE_API = "https://chess-api.com/v1"
33
+
34
+
35
+ if GEMINI_API_KEY == "SUA_CHAVE_API_OPENAI_AQUI" or not GEMINI_API_KEY or len(GEMINI_API_KEY) ==0 :
36
+ print("AVISO: A chave da API GEMINI não foi definida. Por favor, edite o script e insira sua chave.")
37
+ # Considerar sair do script ou lançar um erro se a chave for essencial para a execução completa
38
+ # exit(1)
39
+
40
+ # --- Funções ---
41
+
42
+ def create_or_clear_output_directory():
43
+ """Cria o diretório de saída se não existir."""
44
+ if not os.path.exists(OUTPUT_DIR):
45
+ os.makedirs(OUTPUT_DIR)
46
+ print(f"Diretório criado: {OUTPUT_DIR}")
47
+ else:
48
+ # Limpa todos os arquivos e subdiretórios
49
+ for filename in os.listdir(OUTPUT_DIR):
50
+ file_path = os.path.join(OUTPUT_DIR, filename)
51
+ try:
52
+ if os.path.isfile(file_path) or os.path.islink(file_path):
53
+ os.unlink(file_path)
54
+ elif os.path.isdir(file_path):
55
+ shutil.rmtree(file_path)
56
+ except Exception as e:
57
+ print(f"Erro ao excluir {file_path}: {e}")
58
+ print(f"Diretório limpo: {OUTPUT_DIR}")
59
+
60
+
61
+
62
+
63
+ def encode_image_to_base64(image_path):
64
+ """Codifica um arquivo de imagem (frame) para base64."""
65
+ try:
66
+ with open(image_path, "rb") as image_file:
67
+ return base64.b64encode(image_file.read()).decode('utf-8')
68
+ except FileNotFoundError:
69
+ print(f"Erro: Arquivo de frame não encontrado em {image_path}")
70
+ return None
71
+ except Exception as e:
72
+ print(f"Erro ao codificar o frame {image_path} para base64: {e}")
73
+ return None
74
+
75
+
76
+ def analyze_image_with_gpt(base64_image, prompt):
77
+ if OPENAI_API_KEY:
78
+ try:
79
+ openai_client = OpenAI(api_key=OPENAI_API_KEY)
80
+ print("Cliente OpenAI inicializado.")
81
+ except Exception as e:
82
+ print(f"Erro ao inicializar o cliente OpenAI: {e}. As chamadas de API serão puladas.")
83
+ else:
84
+ print("Chave da API OpenAI não configurada. As chamadas de API serão puladas.")
85
+
86
+ """Envia um frame codificado em base64 para a API GPT-4o e retorna a análise."""
87
+ print(f"Enviando imagem para análise no {GPT_MODEL}...")
88
+
89
+
90
+ payload = {
91
+ "model": GPT_MODEL,
92
+ "messages": [
93
+ {
94
+ "role": "user",
95
+ "content": [
96
+ {
97
+ "type": "text",
98
+ "text": prompt
99
+ },
100
+ {
101
+ "type": "image_url",
102
+ "image_url": {
103
+ "url": f"data:image/png;base64,{base64_image}"
104
+ }
105
+ }
106
+ ]
107
+ }
108
+ ],
109
+ "max_tokens": 100 # Ajuste conforme necessário para a resposta esperada
110
+ }
111
+
112
+ try:
113
+ # Cria o cliente OpenAI dentro da função para garantir que use a chave mais recente
114
+ # (embora seja definida globalmente, isso pode ser útil se a chave for atualizada dinamicamente no futuro)
115
+ # client = OpenAI(api_key=OPENAI_API_KEY)
116
+
117
+ response = openai_client.chat.completions.create(
118
+ model=payload["model"],
119
+ messages=payload["messages"],
120
+ max_tokens=payload["max_tokens"],
121
+ temperature=0
122
+ )
123
+
124
+ # Extrai o conte��do da resposta
125
+ analysis_result = response.choices[0].message.content.strip()
126
+ fen = analysis_result.strip("`")
127
+ fen = fen.replace("_", " ") #retorna _ no lugar de espaço em branco
128
+ print(f"Análise recebida (raw): {analysis_result}")
129
+ print(f"Análise tratada : {fen}")
130
+ if fen != FEN_CORRETA:
131
+ print(f"FEN INCORRETA ")
132
+ else:
133
+ print(f"FEN CORRETA ")
134
+
135
+ return {"image_response": fen}
136
+ except Exception as e:
137
+ print(f"Erro ao chamar a API OpenAI: {e}")
138
+ return {"error": str(e)}
139
+
140
+
141
+ def analyze_image_with_gemini(base64_image, prompt):
142
+ genai.configure(api_key=GEMINI_API_KEY)
143
+ model = genai.GenerativeModel(GEMINI_MODEL)
144
+
145
+ """Envia um frame codificado em base64 para a API GPT-4o e retorna a análise."""
146
+ print(f"Enviando frame para análise no {GEMINI_MODEL}...")
147
+
148
+
149
+ try:
150
+
151
+ response = model.generate_content(
152
+ contents=[
153
+ {
154
+ "role": "user",
155
+ "parts": [
156
+ {f"text": f"{prompt}"},
157
+ {"inline_data": {
158
+ "mime_type": "image/jpeg",
159
+ "data": base64_image
160
+ }}
161
+ ]
162
+ }
163
+ ],
164
+ generation_config={
165
+ "temperature": 0.7,
166
+ "max_output_tokens": 500
167
+ })
168
+
169
+ # Extrai o conteúdo da resposta
170
+ analysis_result = response.text.strip()
171
+ print(f"Análise recebida: {analysis_result}")
172
+
173
+ return {"image_response": analysis_result}
174
+
175
+ except Exception as e:
176
+ print(f"Erro ao chamar a API Gemini: {e}")
177
+ return {"error": str(e)}
178
+
179
+
180
+ def analyze_image_with_chessvision(base64_image):
181
+ base64_image_encoded = f"data:image/jpeg;base64,{base64_image}"
182
+ url = CHESSVISION_TO_FEN_URL
183
+ payload = {
184
+ "board_orientation": "predict",
185
+ "cropped": False,
186
+ "current_player": "black",
187
+ "image": base64_image_encoded,
188
+ "predict_turn": False
189
+ }
190
+
191
+ response = requests.post(url, json=payload)
192
+ if response.status_code == 200:
193
+ dados = response.json()
194
+ if dados.get("success"):
195
+ print(f"Retorno Chessvision {dados}")
196
+ fen = dados.get("result")
197
+ fen = fen.replace("_", " ") #retorna _ no lugar de espaço em branco
198
+ return fen
199
+ else:
200
+ raise Exception("Requisição feita, mas falhou na predição.")
201
+ else:
202
+ raise Exception(f"Erro na requisição: {response.status_code}")
203
+
204
+ def get_best_next_move(fen: str):
205
+ url = CHESS_MOVE_API
206
+ payload = {
207
+ "fen": f"{fen}",
208
+ "depth": 1
209
+ }
210
+ print(f"Buscando melhor movimento em chess-api.com ")
211
+
212
+ response = requests.post(url, json=payload)
213
+ if response.status_code == 200:
214
+ dados = response.json()
215
+ if dados.get("success"):
216
+ move_algebric_notation = dados.get("san")
217
+ move = dados.get("text")
218
+ print(f"Melhor jogada segundo chess-api {move}")
219
+ return move_algebric_notation
220
+ else:
221
+ raise Exception("Requisição feita, mas falhou na predição do próximo movimento.")
222
+ else:
223
+ raise Exception(f"Erro na requisição: {response.status_code}")
224
+
225
+ def save_results_to_json(results_list, output_file):
226
+ """Salva a lista de resultados da análise em um arquivo JSON."""
227
+ print(f"Salvando resultados da análise em {output_file}...")
228
+ try:
229
+ with open(output_file, 'w', encoding='utf-8') as f:
230
+ json.dump(results_list, f, ensure_ascii=False, indent=4)
231
+ print(f"Resultados salvos com sucesso em: {output_file}")
232
+ return True
233
+ except Exception as e:
234
+ print(f"Erro ao salvar os resultados em JSON: {e}")
235
+ return False
236
+
237
+
238
+ # --- Atualização do Bloco Principal ---
239
+ # (Adicionar inicialização do cliente OpenAI e o loop de análise)
240
+ if __name__ == "__main__":
241
+ create_or_clear_output_directory()
242
+ analysis_results_list = []
243
+
244
+ print(f"\nIniciando análise da imagem {IMAGE_FILE} frames com {GEMINI_MODEL}...")
245
+ # Extrai timestamp do nome do arquivo, se possível
246
+ base64_image = encode_image_to_base64(IMAGE_FILE)
247
+ if base64_image:
248
+ # Analisa a imagem com Gemini
249
+ fen = analyze_image_with_chessvision(base64_image) #analyze_image_with_gpt(base64_image, PROMPT_TEXT)
250
+ move = get_best_next_move(fen)
251
+ result_entry = {
252
+ "image": IMAGE_FILE,
253
+ "fen": fen,
254
+ "move": move
255
+ }
256
+ analysis_results_list.append(result_entry)
257
+
258
+ else:
259
+ print(f"Falha ao codificar o frame {IMAGE_FILE}. Pulando análise.")
260
+ analysis_results_list.append({
261
+ "frame_path": IMAGE_FILE,
262
+ "analysis": {"error": "Failed to encode frame to base64."}
263
+ })
264
+
265
+ # break # teste somente uma chamada
266
+ print("\nAnálise de imagem concluída.")
267
+
268
+ # Próxima etapa: Compilar resultados
269
+ print(f"\nPróxima etapa a ser implementada: Compilação dos resultados ({len(analysis_results_list)} análises) em um relatório.")
270
+
271
+
272
+ # ... (código anterior para inicialização, download, extração, análise) ...
273
+
274
+ # Etapa 5: Compilar e Salvar Resultados
275
+ if analysis_results_list:
276
+ print(f"\nCompilando {len(analysis_results_list)} resultados da análise...")
277
+ if save_results_to_json(analysis_results_list, RESULTS_FILE):
278
+ print("Compilação e salvamento dos resultados concluídos.")
279
+ else:
280
+ print("Falha ao salvar os resultados da análise.")
281
+ else:
282
+ print("Nenhum resultado de análise para compilar.")
283
+
284
+ print("\n--- Processo de Análise de Vídeo Concluído ---")
285
+ print(f"Verifique o diretório '{OUTPUT_DIR}' para os frames extraídos (se aplicável).")
286
+ print(f"Verifique o arquivo '{RESULTS_FILE}' para os resultados da análise (se aplicável).")
287
+ print("Lembre-se de substituir os placeholders para URL_DO_SEU_VIDEO_AQUI e SUA_CHAVE_API_OPENAI_AQUI no script.")
288
+
289
+
tool_image_to_fen.py CHANGED
@@ -27,9 +27,9 @@ PROMPT_TEXT = "Analyze the provided image of a chessboard, return the correspond
27
  #PROMPT_TEXT = "You are a chessboard position analyzer. Given an image of a chessboard: - Assume standard orientation: White at the bottom, Black at the top. - Identify all visible pieces and their positions. - Return the FEN string corresponding to the exact position. - Be precise. Do not omit or infer captured pieces. - Return only the FEN, no explanations."
28
  IMAGE_FILE = "arquivos-perguntas/cca530fc-4052-43b2-b130-b30968d8aa44.png"
29
  RESULTS_FILE = os.path.join(OUTPUT_DIR, "analysis_results.json")
30
- FEN_CORRETA = "3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1_b_-_-_0_1"
31
  CHESSVISION_TO_FEN_URL = "http://app.chessvision.ai/predict"
32
-
33
 
34
 
35
  if GEMINI_API_KEY == "SUA_CHAVE_API_OPENAI_AQUI" or not GEMINI_API_KEY or len(GEMINI_API_KEY) ==0 :
@@ -124,6 +124,7 @@ def analyze_image_with_gpt(base64_image, prompt):
124
  # Extrai o conteúdo da resposta
125
  analysis_result = response.choices[0].message.content.strip()
126
  fen = analysis_result.strip("`")
 
127
  print(f"Análise recebida (raw): {analysis_result}")
128
  print(f"Análise tratada : {fen}")
129
  if fen != FEN_CORRETA:
@@ -193,11 +194,34 @@ def analyze_image_with_chessvision(base64_image):
193
  if dados.get("success"):
194
  print(f"Retorno Chessvision {dados}")
195
  fen = dados.get("result")
 
196
  return fen
197
  else:
198
  raise Exception("Requisição feita, mas falhou na predição.")
199
  else:
200
  raise Exception(f"Erro na requisição: {response.status_code}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
  def save_results_to_json(results_list, output_file):
203
  """Salva a lista de resultados da análise em um arquivo JSON."""
@@ -223,10 +247,12 @@ if __name__ == "__main__":
223
  base64_image = encode_image_to_base64(IMAGE_FILE)
224
  if base64_image:
225
  # Analisa a imagem com Gemini
226
- analysis_result = analyze_image_with_chessvision(base64_image) #analyze_image_with_gpt(base64_image, PROMPT_TEXT)
 
227
  result_entry = {
228
  "image": IMAGE_FILE,
229
- "analysis": analysis_result
 
230
  }
231
  analysis_results_list.append(result_entry)
232
 
 
27
  #PROMPT_TEXT = "You are a chessboard position analyzer. Given an image of a chessboard: - Assume standard orientation: White at the bottom, Black at the top. - Identify all visible pieces and their positions. - Return the FEN string corresponding to the exact position. - Be precise. Do not omit or infer captured pieces. - Return only the FEN, no explanations."
28
  IMAGE_FILE = "arquivos-perguntas/cca530fc-4052-43b2-b130-b30968d8aa44.png"
29
  RESULTS_FILE = os.path.join(OUTPUT_DIR, "analysis_results.json")
30
+ FEN_CORRETA = "3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1 b - - 0 1"
31
  CHESSVISION_TO_FEN_URL = "http://app.chessvision.ai/predict"
32
+ CHESS_MOVE_API = "https://chess-api.com/v1"
33
 
34
 
35
  if GEMINI_API_KEY == "SUA_CHAVE_API_OPENAI_AQUI" or not GEMINI_API_KEY or len(GEMINI_API_KEY) ==0 :
 
124
  # Extrai o conteúdo da resposta
125
  analysis_result = response.choices[0].message.content.strip()
126
  fen = analysis_result.strip("`")
127
+ fen = fen.replace("_", " ") #retorna _ no lugar de espaço em branco
128
  print(f"Análise recebida (raw): {analysis_result}")
129
  print(f"Análise tratada : {fen}")
130
  if fen != FEN_CORRETA:
 
194
  if dados.get("success"):
195
  print(f"Retorno Chessvision {dados}")
196
  fen = dados.get("result")
197
+ fen = fen.replace("_", " ") #retorna _ no lugar de espaço em branco
198
  return fen
199
  else:
200
  raise Exception("Requisição feita, mas falhou na predição.")
201
  else:
202
  raise Exception(f"Erro na requisição: {response.status_code}")
203
+
204
+ def get_best_next_move(fen: str):
205
+ url = CHESS_MOVE_API
206
+ payload = {
207
+ "fen": fen,
208
+ "depth": 1
209
+ }
210
+
211
+ print(f"Buscando melhor jogada em {CHESS_MOVE_API} - {payload}")
212
+
213
+ response = requests.post(url, json=payload)
214
+ if response.status_code == 200:
215
+ #print(f"Retorno melhor jogada --> {response.text}")
216
+ dados = response.json()
217
+ move_algebric_notation = dados.get("san")
218
+ move = dados.get("text")
219
+ print(f"Melhor jogada segundo chess-api.com -> {move}")
220
+
221
+ return move_algebric_notation
222
+
223
+ else:
224
+ raise Exception(f"Erro na requisição: {response.status_code}")
225
 
226
  def save_results_to_json(results_list, output_file):
227
  """Salva a lista de resultados da análise em um arquivo JSON."""
 
247
  base64_image = encode_image_to_base64(IMAGE_FILE)
248
  if base64_image:
249
  # Analisa a imagem com Gemini
250
+ fen = analyze_image_with_chessvision(base64_image) #analyze_image_with_gpt(base64_image, PROMPT_TEXT)
251
+ move = get_best_next_move(fen)
252
  result_entry = {
253
  "image": IMAGE_FILE,
254
+ "fen": fen,
255
+ "move": move
256
  }
257
  analysis_results_list.append(result_entry)
258