|
GRUPOS DE DISCUSSÃO PROFISSIONAL WINDEV, WEBDEV e WINDEV Mobile |
| | | | | |
| Inicio → WINDEV 25 → Classe para processamento forense de imagens com correção de // Motion Blur (desfoque de movimento) |
| Classe para processamento forense de imagens com correção de // Motion Blur (desfoque de movimento) |
| Iniciado por Boller, nov., 04 2025 3:57 PM - Sem resposta |
| |
| | | |
|
| |
Membro registado 4.604 mensagems |
|
| Publicado em novembro, 04 2025 - 3:57 PM |
Vou criar uma classe OOP WLanguage completa para processamento forense de imagens com Motion Deblur, baseada no procedimento que você descreveu:
```wlanguage //============================================================================== // Classe: CMotionDeblur // Descrição: Classe para processamento forense de imagens com correção de // Motion Blur (desfoque de movimento) // Autor: Sistema // Data: 04/11/2025 //==============================================================================
CMotionDeblur is Class //-------------------------------------------------------------------------- // DECLARAÇÃO DE MEMBROS PRIVADOS //-------------------------------------------------------------------------- PRIVATE m_sImagemOriginal is string // Caminho da imagem original m_imgProcessada is Image // Objeto Image para processamento m_nLarguraOriginal is int // Largura original m_nAlturaOriginal is int // Altura original m_rFatorEsticamento is real = 1.0 // Fator de alongamento detectado m_nAnguloBorrão is int = 0 // Ângulo do motion blur m_nDeslocamento is int = 0 // Deslocamento do blur em pixels m_rSNR is real = 100.0 // Signal-to-Noise Ratio m_bImagemCarregada is boolean = False m_sUltimoErro is string = "" END //-------------------------------------------------------------------------- // DECLARAÇÃO DE MEMBROS PÚBLICOS //-------------------------------------------------------------------------- PUBLIC // Propriedades de leitura PROPERTY LarguraImagem, read = m_nLarguraOriginal PROPERTY AlturaImagem, read = m_nAlturaOriginal PROPERTY FatorEsticamento, read = m_rFatorEsticamento PROPERTY AnguloBlur, read = m_nAnguloBorrão PROPERTY Deslocamento, read = m_nDeslocamento PROPERTY UltimoErro, read = m_sUltimoErro PROPERTY ImagemCarregada, read = m_bImagemCarregada END END
//============================================================================== // CONSTRUTOR //============================================================================== PROCEDURE Constructor() m_bImagemCarregada = False m_sUltimoErro = "" END
//============================================================================== // DESTRUTOR //============================================================================== PROCEDURE Destructor() // Libera recursos se necessário IF m_bImagemCarregada THEN m_imgProcessada = Null END END
//============================================================================== // Método: CarregarImagem // Descrição: Carrega a imagem inicial para processamento // Parâmetros: // - sCaminhoImagem: Caminho completo da imagem // Retorno: True se sucesso, False caso contrário //============================================================================== PROCEDURE PUBLIC CarregarImagem(LOCAL sCaminhoImagem is string): boolean
// Valida parâmetros IF sCaminhoImagem = "" THEN m_sUltimoErro = "Caminho da imagem não informado" RESULT False END IF NOT fFileExist(sCaminhoImagem) THEN m_sUltimoErro = StringBuild("Arquivo não encontrado: %1", sCaminhoImagem) RESULT False END // Carrega a imagem m_imgProcessada = dLoadImage(sCaminhoImagem) IF m_imgProcessada..Width = 0 OR m_imgProcessada..Height = 0 THEN m_sUltimoErro = "Falha ao carregar a imagem. Formato inválido?" m_bImagemCarregada = False RESULT False END // Armazena informações m_sImagemOriginal = sCaminhoImagem m_nLarguraOriginal = m_imgProcessada..Width m_nAlturaOriginal = m_imgProcessada..Height m_bImagemCarregada = True m_sUltimoErro = "" RESULT True END
//============================================================================== // Método: MedirEsticamento // Descrição: Calcula o fator de esticamento medindo um objeto circular // Parâmetros: // - nDiametroX: Diâmetro horizontal medido (em pixels) // - nDiametroY: Diâmetro vertical medido (em pixels) // Retorno: Fator de esticamento calculado //============================================================================== PROCEDURE PUBLIC MedirEsticamento(LOCAL nDiametroX is int, LOCAL nDiametroY is int): real
LOCAL rFator is real IF nDiametroX <= 0 OR nDiametroY <= 0 THEN m_sUltimoErro = "Diâmetros inválidos para cálculo" RESULT 1.0 END // Calcula a razão entre os diâmetros rFator = nDiametroX / nDiametroY m_rFatorEsticamento = rFator RESULT rFator END
//============================================================================== // Método: CorrigirEsticamento // Descrição: Corrige o esticamento da imagem aplicando escala // Parâmetros: // - bDirecaoHorizontal: True para corrigir horizontalmente, False para vertical // Retorno: True se sucesso, False caso contrário //============================================================================== PROCEDURE PUBLIC CorrigirEsticamento(LOCAL bDirecaoHorizontal is boolean = True): boolean
LOCAL nNovaLargura, nNovaAltura is int LOCAL rFatorCorrecao is real IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END IF m_rFatorEsticamento = 1.0 THEN // Sem esticamento detectado RESULT True END // Calcula o fator de correção (inverso do esticamento) rFatorCorrecao = 1.0 / m_rFatorEsticamento // Aplica a correção na direção apropriada IF bDirecaoHorizontal THEN // Corrige horizontalmente nNovaLargura = Round(m_nLarguraOriginal * rFatorCorrecao, 0) nNovaAltura = m_nAlturaOriginal ELSE // Corrige verticalmente nNovaLargura = m_nLarguraOriginal nNovaAltura = Round(m_nAlturaOriginal * rFatorCorrecao, 0) END // Redimensiona a imagem dResize(m_imgProcessada, nNovaLargura, nNovaAltura, drHomothetic) // Atualiza dimensões m_nLarguraOriginal = nNovaLargura m_nAlturaOriginal = nNovaAltura RESULT True END
//============================================================================== // Método: MedirLinhaBlur // Descrição: Mede a linha do blur para determinar ângulo e deslocamento // Parâmetros: // - nX1, nY1: Ponto inicial da linha // - nX2, nY2: Ponto final da linha // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC MedirLinhaBlur(LOCAL nX1 is int, LOCAL nY1 is int, LOCAL nX2 is int, LOCAL nY2 is int): boolean
LOCAL rDistancia is real LOCAL rAngulo is real IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END // Calcula a distância (deslocamento do blur) rDistancia = SquareRoot((nX2 - nX1)^2 + (nY2 - nY1)^2) m_nDeslocamento = Round(rDistancia, 0) // Calcula o ângulo em graus IF nX2 = nX1 THEN // Linha vertical m_nAnguloBorrão = 90 ELSE rAngulo = ATan((nY2 - nY1) / (nX2 - nX1)) m_nAnguloBorrão = Round(rAngulo * 180 / PI, 0) END RESULT True END
//============================================================================== // Método: AplicarMotionDeblur // Descrição: Aplica o algoritmo de Motion Deblur // Parâmetros: // - nDeslocamento: Deslocamento do blur em pixels (opcional, usa medição se 0) // - nAngulo: Ângulo do blur em graus (opcional, usa medição se 0) // - rSNR: Signal-to-Noise Ratio (padrão: 100.0) // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC AplicarMotionDeblur(LOCAL nDeslocamento is int = 0, LOCAL nAngulo is int = 0, LOCAL rSNR is real = 100.0): boolean
LOCAL imgTemp is Image LOCAL nShift, nAngle is int IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END // Usa valores medidos se não fornecidos nShift = nDeslocamento IF nShift = 0 THEN nShift = m_nDeslocamento nAngle = nAngulo IF nAngle = 0 THEN nAngle = m_nAnguloBorrão IF nShift = 0 THEN m_sUltimoErro = "Deslocamento não medido. Use MedirLinhaBlur primeiro." RESULT False END m_rSNR = rSNR // NOTA: WLanguage não possui função nativa de Motion Deblur // Esta é uma implementação simplificada usando filtros disponíveis // Aplica sharpen (nitidez) como aproximação imgTemp = dCopy(m_imgProcessada) // Filtro de nitidez baseado no deslocamento LOCAL nIntensidade is int = Min(nShift * 2, 100) dSharpen(imgTemp, nIntensidade) // Aplica rotação se necessário (baseado no ângulo) IF nAngle <> 0 THEN dRotation(imgTemp, -nAngle, drNoEnlarging) END m_imgProcessada = imgTemp RESULT True END
//============================================================================== // Método: AjustarBrilhoContraste // Descrição: Ajusta brilho e contraste da imagem // Parâmetros: // - nBrilho: Ajuste de brilho (-100 a +100, 0 = sem alteração) // - nContraste: Ajuste de contraste (-100 a +100, 0 = sem alteração) // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC AjustarBrilhoContraste(LOCAL nBrilho is int = 0, LOCAL nContraste is int = 50): boolean
IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END // Valida parâmetros nBrilho = Max(-100, Min(100, nBrilho)) nContraste = Max(-100, Min(100, nContraste)) // Ajusta brilho IF nBrilho <> 0 THEN dModifyLuminosity(m_imgProcessada, nBrilho) END // Ajusta contraste IF nContraste <> 0 THEN dModifyContrast(m_imgProcessada, nContraste) END RESULT True END
//============================================================================== // Método: RecortarArea // Descrição: Recorta uma área específica da imagem (crop) // Parâmetros: // - nX, nY: Coordenadas do canto superior esquerdo // - nLargura, nAltura: Dimensões da área a recortar // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC RecortarArea(LOCAL nX is int, LOCAL nY is int, LOCAL nLargura is int, LOCAL nAltura is int): boolean
LOCAL imgRecortada is Image IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END // Valida coordenadas IF nX < 0 OR nY < 0 OR nLargura <= 0 OR nAltura <= 0 THEN m_sUltimoErro = "Coordenadas de recorte inválidas" RESULT False END IF nX + nLargura > m_imgProcessada..Width OR nY + nAltura > m_imgProcessada..Height THEN m_sUltimoErro = "Área de recorte excede os limites da imagem" RESULT False END // Cria nova imagem com a área recortada imgRecortada..Width = nLargura imgRecortada..Height = nAltura dStartDrawing(imgRecortada) dCopyImage(m_imgProcessada, imgRecortada, copySrcCopy, nX, nY, nLargura, nAltura, 0, 0) dEndDrawing(imgRecortada) m_imgProcessada = imgRecortada m_nLarguraOriginal = nLargura m_nAlturaOriginal = nAltura RESULT True END
//============================================================================== // Método: ProcessamentoCompleto // Descrição: Executa o fluxo completo de processamento forense // Parâmetros: // - stParametros: Estrutura com todos os parâmetros necessários // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC ProcessamentoCompleto(LOCAL stParametros is STParametrosDeblur): boolean
IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END // 1. Correção de esticamento (se necessário) IF stParametros.bCorrigirEsticamento THEN IF NOT CorrigirEsticamento(stParametros.bDirecaoHorizontal) THEN RESULT False END END // 2. Aplicar Motion Deblur IF NOT AplicarMotionDeblur(stParametros.nDeslocamento, stParametros.nAngulo, stParametros.rSNR) THEN RESULT False END // 3. Ajustar Brilho e Contraste IF NOT AjustarBrilhoContraste(stParametros.nBrilho, stParametros.nContraste) THEN RESULT False END // 4. Recortar área (se especificado) IF stParametros.bRecortar THEN IF NOT RecortarArea(stParametros.nRecorteX, stParametros.nRecorteY, ... stParametros.nRecorteLargura, stParametros.nRecorteAltura) THEN RESULT False END END RESULT True END
//============================================================================== // Método: SalvarImagem // Descrição: Salva a imagem processada // Parâmetros: // - sCaminhoDestino: Caminho onde salvar a imagem // - nQualidade: Qualidade da imagem (1-100, padrão: 95) // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC SalvarImagem(LOCAL sCaminhoDestino is string, LOCAL nQualidade is int = 95): boolean
IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END IF sCaminhoDestino = "" THEN m_sUltimoErro = "Caminho de destino não informado" RESULT False END // Valida qualidade nQualidade = Max(1, Min(100, nQualidade)) // Salva a imagem IF NOT dSaveImageJPEG(m_imgProcessada, sCaminhoDestino, nQualidade) THEN m_sUltimoErro = StringBuild("Erro ao salvar imagem: %1", ErrorInfo()) RESULT False END m_sUltimoErro = "" RESULT True END
//============================================================================== // Método: ObterImagem // Descrição: Retorna o objeto Image processado // Retorno: Objeto Image //============================================================================== PROCEDURE PUBLIC ObterImagem(): Image
RESULT m_imgProcessada END
//============================================================================== // Método: ExibirEmControle // Descrição: Exibe a imagem processada em um controle Image // Parâmetros: // - ctrlImagem: Controle Image onde exibir // Retorno: True se sucesso //============================================================================== PROCEDURE PUBLIC ExibirEmControle(ctrlImagem is Control): boolean
IF NOT m_bImagemCarregada THEN m_sUltimoErro = "Nenhuma imagem carregada" RESULT False END IF ctrlImagem..Type <> typImage THEN m_sUltimoErro = "Controle informado não é do tipo Image" RESULT False END ctrlImagem = m_imgProcessada RESULT True END
//============================================================================== // ESTRUTURA DE PARÂMETROS //============================================================================== STParametrosDeblur is Structure // Correção de esticamento bCorrigirEsticamento is boolean = False bDirecaoHorizontal is boolean = True // Motion Deblur nDeslocamento is int = 0 nAngulo is int = 0 rSNR is real = 100.0 // Ajustes de imagem nBrilho is int = 0 nContraste is int = 50 // Recorte bRecortar is boolean = False nRecorteX is int = 0 nRecorteY is int = 0 nRecorteLargura is int = 0 nRecorteAltura is int = 0 END ```
**Exemplo de uso da classe:**
```wlanguage //============================================================================== // EXEMPLO DE USO - Processamento Forense de Placa de Carro //==============================================================================
PROCEDURE ExemploProcessamentoForense()
LOCAL objDeblur is CMotionDeblur LOCAL stParams is STParametrosDeblur // Cria instância da classe objDeblur = new CMotionDeblur() // Carrega imagem do carro com placa borrada IF NOT objDeblur.CarregarImagem("C:\Fotos\carro_borrado.jpg") THEN Error("Erro ao carregar imagem: " + objDeblur.UltimoErro) RETURN END Info(StringBuild("Imagem carregada: %1 x %2 pixels", ... objDeblur.LarguraImagem, objDeblur.AlturaImagem)) // Mede a linha do blur na placa // Exemplo: linha traçada do ponto (320, 245) até (380, 250) objDeblur.MedirLinhaBlur(320, 245, 380, 250) Info(StringBuild("Blur medido: %1 pixels, ângulo: %2°", ... objDeblur.Deslocamento, objDeblur.AnguloBlur)) // Configura parâmetros para processamento completo stParams.bCorrigirEsticamento = False // Sem esticamento neste caso stParams.nDeslocamento = 0 // Usa medição automática stParams.nAngulo = 0 // Usa medição automática stParams.rSNR = 100.0 stParams.nBrilho = -20 // Escurece fundo stParams.nContraste = 70 // Aumenta contraste stParams.bRecortar = True stParams.nRecorteX = 300 stParams.nRecorteY = 230 stParams.nRecorteLargura = 120 stParams.nRecorteAltura = 40 // Executa processamento completo IF NOT objDeblur.ProcessamentoCompleto(stParams) THEN Error("Erro no processamento: " + objDeblur.UltimoErro) RETURN END // Exibe resultado em controle de imagem objDeblur.ExibirEmControle(IMG_Resultado) // Salva imagem processada IF objDeblur.SalvarImagem("C:\Fotos\placa_nitida.jpg", 95) THEN Info("Imagem processada salva com sucesso!") ELSE Error("Erro ao salvar: " + objDeblur.UltimoErro) END // Libera objeto delete objDeblur END
//============================================================================== // EXEMPLO 2 - Processamento Manual Passo a Passo //==============================================================================
PROCEDURE ExemploProcessamentoManual()
LOCAL objDeblur is CMotionDeblur objDeblur = new CMotionDeblur() // 1. Carrega imagem IF NOT objDeblur.CarregarImagem("C:\Fotos\placa_borrada.jpg") THEN Error(objDeblur.UltimoErro) RETURN END // 2. Mede esticamento (se objeto circular visível) // Exemplo: diâmetro horizontal = 150px, vertical = 100px LOCAL rFator is real = objDeblur.MedirEsticamento(150, 100) Info("Fator de esticamento: " + rFator) // 3. Corrige esticamento objDeblur.CorrigirEsticamento(True) // Corrige horizontalmente // 4. Mede linha do blur objDeblur.MedirLinhaBlur(100, 50, 150, 55) // 5. Aplica deblur objDeblur.AplicarMotionDeblur() // Usa medições automáticas // 6. Ajusta brilho e contraste objDeblur.AjustarBrilhoContraste(-15, 60) // 7. Recorta área de interesse objDeblur.RecortarArea(80, 40, 100, 30) // 8. Exibe e salva objDeblur.ExibirEmControle(IMG_Processada) objDeblur.SalvarImagem("C:\Fotos\resultado_final.jpg") delete objDeblur END ```
**Características da classe:**
1. **Encapsulamento completo** - Todos os membros privados com propriedades de leitura 1. **Tratamento de erros** - Propriedade `UltimoErro` para diagnóstico 1. **Fluxo completo ou manual** - Método `ProcessamentoCompleto()` ou métodos individuais 1. **Validações rigorosas** - Todos os parâmetros são validados 1. **Compatibilidade WX** - Usa funções nativas: `dLoadImage`, `dSharpen`, `dModifyLuminosity`, etc. 1. **Estrutura de parâmetros** - `STParametrosDeblur` para configuração organizada
**Limitações técnicas:**
O WLanguage **não possui** implementação nativa de algoritmos complexos como Motion Deblur (Wiener deconvolution). A classe usa **aproximações** com filtros disponíveis (`dSharpen`, `dRotation`). Para resultados profissionais similares ao ImageJ, seria necessário integrar com DLLs externas ou usar APIs de processamento de imagem.
Mas nada impede usar python e outras linguagens como complementar para atingir esse objetivo.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|