Sunday 14 April 2019

Moving average opencv


Ainda estou cortando um script de digitalização de livros e, por enquanto, tudo o que preciso é poder detectar automaticamente uma página. O livro preenche 90 da tela (estou usando uma webcam cruddy para a detecção de movimento), então quando eu virar uma página, a direção do movimento é basicamente na mesma direção. Modifiquei um script de acompanhamento de movimento, mas os derivados não me levam a lugar nenhum: detecta o movimento médio do centro médio de todas as caixas, o que é extremamente ineficiente. Como eu iria sobre a detecção de tais movimentos de forma rápida e precisa (ou seja, dentro de um limiar) Estou usando Python, e eu pretendo ficar com ele, como toda a minha estrutura é baseada em Python. E ajuda é apreciada, por isso, obrigado a todos com antecedência. Cheers. Hi, este vai ser um artigo muito simples, mas você vai encontrá-lo muito útil. Trata-se de extração de fundo de um vídeo. Suponha que você é dado vídeo de filmagens de tráfego, pode ser alguma coisa como esta. Tráfego na Índia. E você é solicitado a encontrar um plano de fundo aproximado. Ou qualquer coisa assim. A extração de backgrounds é importante no rastreamento de objetos. Se você já tem uma imagem do fundo nua, então é simples. Mas em muitos casos, você não vai ter uma imagem e assim, você terá que criar um. Isso é onde Running Average vem a calhar. (Eu pensei sobre isso quando um cara fez uma pergunta no SOF. Link) A função que usamos aqui para encontrar Running Average é cv2.accumulateWeighted (). Por exemplo, se estamos assistindo a um vídeo, continuamos alimentando cada quadro para essa função ea função continua encontrando as médias de todos os quadros alimentados conforme a relação abaixo: src não é nada além de nossa imagem de origem. Pode ser em escala de cinza ou imagem colorida e ponto flutuante de 8 ou 32 bits. Dst é a imagem de saída ou acumulador com os mesmos canais que a da imagem de origem, e é de 32 bits ou de 64 bits ponto flutuante. Além disso, devemos declará-lo primeiro a um valor que será tomado como valor inicial. Alpha é o peso da imagem de entrada. De acordo com o Docs, o alfa regula a velocidade de atualização (o quão rápido o acumulador 8220forgets8221 sobre imagens anteriores). Em palavras simples, se o alfa é um valor mais alto, a imagem média tenta pegar mesmo mudanças muito rápidas e curtas nos dados. Se for valor mais baixo, a média torna-se lenta e não considerará mudanças rápidas nas imagens de entrada. Vou explicar um pouco com a ajuda de imagens no final do artigo. No código acima, eu configurei duas médias, uma com maior valor alfa e outra com menor valor alfa para que você possa entender o efeito de alfa. No início, ambos são definidos para o quadro inicial da captura. E no laço eles são atualizados. Você pode ver alguns resultados no link SOF que já forneci. (Eu forneço os resultados aqui, você pode verificar o código e valor alfa lá): Eu usei minha webcam e salva frame original e média em execução em um determinado instante. Este é um quadro de um vídeo de tráfego típico tomado por uma câmera estacionária. Como você pode ver, um carro está indo na estrada, ea pessoa está tentando atravessar a estrada em um determinado instante de tempo. Mas veja a média corrente naquele tempo. Não há nenhuma pessoa e carro nesta imagem (na verdade é lá, tem um olhar mais atento, então você vai vê-lo, ea pessoa é mais clara do que o carro, uma vez que o carro está se movendo muito rápido e através da imagem, não tem muito Efeito, em média, mas a pessoa está lá por um longo tempo, já que ele é lento e se movendo em toda a estrada.) Agora precisamos ver o efeito de alfa nessas imagens. Imagens suaves Objetivos Aprenda a: Aplicar filtros personalizados a imagens (convolução 2D) Convolução 2D (Filtragem de Imagem) Como para sinais unidimensionais, as imagens também podem ser filtradas com vários filtros passa-baixa (LPF), filtros passa-alta (HPF), etc. LPF ajuda na remoção de ruído ou embaçamento da imagem. Um filtro HPF ajuda a encontrar bordas em uma imagem. OpenCV fornece uma função, cv2.filter2D (). Para convolver um kernel com uma imagem. Como exemplo, vamos tentar um filtro de média em uma imagem. Um kernel de filtro de média de 5x5 pode ser definido da seguinte maneira: Filtrando com o resultado do kernel acima resulta o seguinte sendo executado: para cada pixel, uma janela 5x5 é centrada neste pixel, todos os pixels que caem dentro desta janela são resumidos eo resultado é Então dividido por 25. Isso equivale a calcular a média dos valores de pixels dentro dessa janela. Esta operação é executada para todos os pixels da imagem para produzir a imagem filtrada de saída. Experimente este código e verifique o resultado: Blurring de imagem (Suavização de imagem) O desfoque de imagem é conseguido convertendo a imagem com um kernel de filtro passa-baixa. É útil para remover o ruído. Ele realmente remove o conteúdo de alta freqüência (por exemplo, ruído, bordas) da imagem resultando em bordas sendo desfocada quando este é filtro é aplicado. (Bem, há técnicas de desfocagem que não desfocam bordas). OpenCV fornece principalmente quatro tipos de técnicas de desfoque. 1. Estabelecimento de média Isso é feito convolvendo a imagem com um filtro de caixa normalizado. Ele simplesmente leva a média de todos os pixels sob a área do kernel e substitui o elemento central por essa média. Isso é feito pela função cv2.blur () ou cv2.boxFilter (). Verifique os documentos para obter mais detalhes sobre o kernel. Devemos especificar a largura ea altura do kernel. Um filtro caixa 3x3 normalizado seria semelhante a este: Se você don8217t deseja usar um filtro de caixa normalizada, use cv2.boxFilter () e passar o argumento normalizeFalse para a função. Verifique a demo de exemplo abaixo com um kernel de tamanho 5x5: 2. Filtragem Gaussiana Nesta abordagem, em vez de um filtro de caixa consistindo de coeficientes de filtro iguais, um kernel gaussiano é usado. É feito com a função, cv2.GaussianBlur (). Devemos especificar a largura ea altura do kernel que deve ser positivo e ímpar. Também devemos especificar o desvio padrão nas direções X e Y, sigmaX e sigmaY, respectivamente. Se apenas o sigmaX for especificado, sigmaY é tomado como igual a sigmaX. Se ambos são dados como zeros, eles são calculados a partir do tamanho do kernel. A filtragem gaussiana é altamente eficaz na remoção do ruído gaussiano da imagem. Se você quiser, você pode criar um kernel gaussiano com a função, cv2.getGaussianKernel (). O código acima pode ser modificado para borrar Gaussian: 3. Median Filtering Aqui, a função cv2.medianBlur () calcula a mediana de todos os pixels sob a janela do kernel eo pixel central é substituído por esse valor mediano. Isso é altamente eficaz na remoção de ruído de sal e pimenta. Uma coisa interessante a notar é que, nos filtros Gaussiano e Box, o valor filtrado para o elemento central pode ser um valor que pode não existir na imagem original. No entanto, este não é o caso na mediana de filtragem, uma vez que o elemento central é sempre substituído por algum valor de pixel na imagem. Isso reduz o ruído de forma eficaz. O tamanho do kernel deve ser um inteiro ímpar positivo. Nesta demonstração, adicionamos um ruído de 50 à nossa imagem original e usamos um filtro mediano. Verifique o resultado: 4. Filtragem Bilateral Como observamos, os filtros que apresentamos anteriormente tendem a desfocar bordas. Este não é o caso para o filtro bilateral, cv2.bilateralFilter (). Que foi definido para, e é altamente eficaz na remoção de ruído enquanto preserva bordas. Mas a operação é mais lenta em comparação com outros filtros. Já vimos que um filtro gaussiano toma a vizinhança ao redor do pixel e encontra sua média ponderada gaussiana. Este filtro gaussiano é uma função do espaço sozinho, isto é, os pixels próximos são considerados durante a filtragem. Ele não considera se pixels têm quase o mesmo valor de intensidade e não considera se o pixel está em uma borda ou não. O efeito resultante é que os filtros gaussianos tendem a desfocar bordas, o que é indesejável. O filtro bilateral também usa um filtro gaussiano no domínio espacial, mas também usa mais um componente de filtro (multiplicativo) gaussiano que é uma função das diferenças de intensidade de pixels. A função gaussiana do espaço garante que apenas os pixels são vizinhos 8217spatial8217 são considerados para a filtragem, enquanto que o componente gaussiano aplicado no domínio de intensidade (uma função gaussiana das diferenças de intensidade) garante que apenas aqueles pixels com intensidades semelhantes ao do pixel central 8216, vizinhos8217) para calcular o valor de intensidade desfocada. Como resultado, este método preserva bordas, uma vez que para pixels situados perto de bordas, os pixels vizinhos colocados no outro lado da aresta e, portanto, exibindo grandes variações de intensidade quando comparados com o pixel central, não serão incluídos para desfocagem. O exemplo abaixo demonstra o uso de filtragem bilateral (Para detalhes sobre argumentos, consulte os documentos do OpenCV). Observe que a textura na superfície desapareceu, mas as arestas ainda são preservadas.// MotionDetection. cpp. Define o ponto de entrada para o aplicativo de console. // // Contourold. cpp. Define o ponto de entrada para o aplicativo de console. // include stdafx. h incluir iostream include stdlib. h // OpenCV inclui. Include cv. h include highgui. h pragma comentário (lib, cv. lib) pragma comentário (lib, cxcore. lib) pragma comentário (lib, highgui. lib) usando namespace std int main (int argc, char argv) Uma nova janela. CvNamedWindow (My Window, CVWINDOWAUTOSIZE) // Criar um novo objeto de captura de filme. CvCapture input // Atribuir o filme a capturar. // inputMovie cvCaptureFromAVI (vinoth. avi) char fileName D: highway. avi // char fileName D: ProfileAVIcardriving. wmv entrada cvCaptureFromFile (fileName) if (entrada) cout hnext) // Obtém um retângulo delimitador em torno do objeto em movimento. BndRect cvBoundingRect (contorno, 0) pt1.x bndRect. x pt1.y bndRect. y pt2.x bndRect. x bndRect. width pt2.y bndRect. y bndRect. height // Obtém uma posição X média do contorno em movimento. AvgX (pt1.x pt2.x) / 2 // Se o contorno estiver dentro dos limites do edifício. If (avgX 90 avgX 88 closerToLeft prevX) // Aumente o número de pessoas. NumPeople // Reponha o objeto mais próximo ao indicador esquerdo. CloserToLeft 0 // else se o contorno anterior estava dentro de 2 do limite direito. Else if (nextToRight 250 closerToRight closerToLeft avgX 250) closerToRight avgX // Salva o valor atual de X para usar como o anterior na próxima iteração. PrevX avgX // Escreve o número de pessoas contadas na parte superior do quadro de saída. CvInitFont (fonte, CVFONTHERSHEYSIMPLEX, 0.8, 0.8, 0, 2) cvPutText (colourImage, itoa (numPeople, wow, 10), cvPoint (60, 200), fonte, cvScalar (0, 0, 300) . CvShowImage (Minha janela, colourImage) // Espere que o usuário o veja. CvWaitKey (10) // Escreva a moldura para o filme de saída. CvWriteFrame (outputMovie, colourImage) // Destrua a imagem, filmes e janela. CvReleaseImage (temp) cvReleaseImage (diferença) cvReleaseImage (greyImage) cvReleaseImage (movingAverage) cvDestroyWindow (Minha janela) Detecção de movimento pode ser feito através deste programa. Este código contém o código para gravar o movimento vídeo detectado para o arquivo de saída. Aqui eles hardcoded os valores para detectar as pessoas no vídeo. Precisamos remover o código como AvgX, closerToLeft e closerToRight como estes. É uma coisa suficiente para usar o desenhar o retângulo em todos os objetos em movimento. Imagens suaves A explicação abaixo pertence ao livro Computer Vision: Algorithms and Applications de Richard Szeliski e LearningOpenCV Smoothing. Também chamado de borrão. É uma operação de processamento de imagem simples e freqüentemente usada. Existem muitas razões para suavizar. Neste tutorial vamos nos concentrar no alisamento para reduzir o ruído (outros usos serão vistos nos tutoriais a seguir). Para executar uma operação de suavização, aplicaremos um filtro à nossa imagem. O tipo mais comum de filtros são lineares. Em que um valor de pixel de saída 8217s (isto é) é determinado como uma soma ponderada de valores de pixel de entrada (isto é): Ajuda a visualizar um filtro como uma janela de coeficientes deslizando através da imagem. Existem muitos tipos de filtros, aqui vamos mencionar os mais utilizados: Filtro de caixa normalizada Este filtro é o mais simples de todos Cada pixel de saída é a média de seus vizinhos do kernel (todos eles contribuem com pesos iguais) O kernel está abaixo: Gaussian Filtro Provavelmente o filtro mais útil (embora não o mais rápido). A filtragem gaussiana é feita convolvendo cada ponto na matriz de entrada com um kernel gaussiano e, em seguida, somando-os todos para produzir a matriz de saída. Apenas para tornar a imagem mais clara, lembre-se de como um kernel 1D gaussiano parece Assumir que uma imagem é 1D, você pode notar que o pixel localizado no meio teria o maior peso. O peso de seus vizinhos diminui à medida que a distância espacial entre eles eo pixel central aumenta. Lembre-se que um Gaussiano 2D pode ser representado como: Filtro Mediano O filtro mediano percorre cada elemento do sinal (neste caso a imagem) e substitui cada pixel pela mediana de seus pixels vizinhos (localizados em uma vizinhança quadrada ao redor do pixel avaliado ). Filtro Bilateral Até agora, explicamos alguns filtros cujo principal objetivo é suavizar uma imagem de entrada. No entanto, às vezes os filtros não só dissolver o ruído, mas também afastar as bordas. Para evitar isso (pelo menos em certa medida), podemos usar um filtro bilateral. De forma análoga ao filtro gaussiano, o filtro bilateral também considera os pixels vizinhos com pesos atribuídos a cada um deles. Estes pesos têm duas componentes, a primeira das quais é a mesma ponderação utilizada pelo filtro Gaussiano. O segundo componente leva em conta a diferença de intensidade entre os pixels vizinhos e o avaliado. Para uma explicação mais detalhada, você pode verificar este link Código O que este programa faz Carrega uma imagem Aplica 4 tipos diferentes de filtros (explicados em Teoria) e mostra as imagens filtradas sequencialmente Explicação Let8217s verifica as funções OpenCV que envolvem apenas o procedimento de suavização, uma vez que O resto já é conhecido por agora. Filtro de Bloqueio Normalizado: O OpenCV oferece a função de desfocagem para realizar a suavização com este filtro. Nós especificamos 4 argumentos (mais detalhes, verifique a Referência): src. Imagem de origem dst. Tamanho da imagem de destino (w, h). Define o tamanho do kernel a ser usado (de largura w pixels e altura h pixels) Ponto (-1, -1). Indica onde o ponto de ancoragem (o pixel avaliado) está localizado em relação à vizinhança. Se houver um valor negativo, então o centro do kernel é considerado o ponto de ancoragem. É executado pela função GaussianBlur: Aqui usamos 4 argumentos (mais detalhes, verifique a referência do OpenCV):

No comments:

Post a Comment