Introdução à Programação (B) (2017/2018)

Enunciado do Projeto

Artur Miguel Dias


Calendário

Changelog

Durante a realização do trabalho, este enunciado poderá ser submetido a melhorias, correções e clarificações. Por exemplo, as dúvidas colocadas pelos alunos poderão resultar em algumas clarificações ou explicações suplementares. As alterações serão listadas nesta secção.


Imagens

Apresentação do projeto

O objetivo deste projeto é implementar em C um conjunto de transformações de imagens. No contexto das comunidades sociais de partilha de fotos, como o Instagram, estas transformações costumam ser designadas de filtros.

Para guardar as imagens em ficheiro, usaremos o formato PNG. Trata-se dum formato bastante popular, suportado por praticamente todas as aplicações que mostram imagens, incluindo os browsers da Web.

Para ler e escrever em ficheiro as nossas imagens, que estão em formato PNG, usaremos o excelente codificador/descodificador escrito por Lode Vandevenne.

Para representar cada imagem em memória, usaremos uma matriz de píxeis coloridos. Desta forma, o nosso projeto vai enfatizar o processamento de matrizes em C.

O programa dialoga com o utilizador através dum interpretador de comandos muito semelhante ao do exercício 36 da aula prática 10.

Aspetos importantes

Pedimos-lhe para escrever código de qualidade, portanto muito legível (fácil de entender), constituído por numerosas funções, geralmente pequenas e sempre com nomes bem escolhidos. Além das matrizes, você também terá a oportunidade de praticar a utilização de funções, ciclos, vetores, registos, ficheiros, strings, etc.

A entrega do seu projeto será feita através dum concurso do Mooshak que será aberto mais tarde.

Este projeto é para ser realizado por grupos de dois alunos.

Ficheiros disponibilizados

Fornecemos-lhe o seguinte arquivo zip: imagens.zip. Expanda o arquivo e copie o seu conteúdo (5 ficheiros e 1 pasta) para dentro para pasta do seu projeto no CodeBlocks. Agora entre no CodeBlocks e use o comando "Project > Add Files..." para adicionar os 5 ficheiros ao projeto. Se existir um ficheiro "main.c" elimine-o.

A estrutura do arquivo é a seguinte:

Descrição:

Representação e processamento das imagens

Apresentamos agora os tipos mais importantes do programa.

Tipo Int2

Eis a definição do tipo Int2: Este tipo agrega dois campos inteiros no mesmo registo.

Façamos uma analogia com os vetores tradicionais: Quando trabalhamos com vetores unidimensionais, usamos inteiros para representar o tamanho dos vetores (muitas vezes, usando um parâmetro chamado n) e para implementar os índices dos ciclos que percorrem os vetores (muitas vezes, usando uma variável chamada i). No caso dos vetores bidimensionais, é prático usar entidades de Int2 nas mesmas duas situações.

Tipo Pixel

Eis a definição do tipo Pixel: Uma imagem digital é constituída por numerosos elementos atómicos, cada um dos quais com cor uniforme. Cada um desses elementos chama-se um píxel (pixel, em Inglês).

Para representar um píxel, basta indicar a sua cor, e isso é feito usando o chamado formato RGB, onde R significa "red", G significa "green" e B significa "blue". Qualquer cor pode ser obtida pela mistura em proporções variáveis das três cores básicas. Os artistas pintores sabem há muito que, para obter a cor lilás, devem misturar vermelho com azul.

Portanto as nossas cores são definidas por três componentes a que chamamos vermelho, verde, azul. Usaremos 256 níveis de intensidade para cada uma das 3 componentes, ou seja o valor de cada componente vai variar desde a intensidade mínima de 0 até à intensidade máxima de 255 (= MAX_COR). Também seria possível usar 65536 níveis de intensidade e trabalhar a cor com maior precisão, até porque o formato PNG suporta imagens com os dois níveis de precisão nas cores. Mas já satisfaz bastante usar 256 níveis: repare que com 256 níveis podemos representar mais de 16 milhões de cores distintas, mais exatamente 256*256*256 = 16777216.

Quando as três componentes duma cor são iguais, obtêm-se níveis de cinzento. Veja estas três cores, todas com as três componentes iguais:

Tipo Imagem

Eis a definição do tipo Imagem:

Uma imagem é uma matriz (vetor bidimensional) de píxeis. Repare que a definição do tipo Imagem só indica a largura MAX_X e altura MAX_Y máximas da matriz. Para indicar o tamanho real duma imagem, precisamos de a acompanhar por um valor de tipo Int2. Esse valor determina qual a porção da matriz que é efetivamente usada. Tal como no caso dos vetores unidimensionais, os vetores bidimensionais também precisam de companhia.

Para exemplificar, a função seguinte copia uma imagem img, com tamanho n, para a imagem res. A função retorna o tamanho da cópia, que neste caso é igual ao tamanho da imagem original. Para percorrer a matriz usam-se dois ciclos, um dentro do outro. O ciclo exterior percorre linhas de cima para baixo. O ciclo interior percorre cada linha da esquerda para a direita, avançando ao longo de colunas. Usa-se uma variável i para controlar evolução dos dois ciclos e para controlar o acesso às várias posições das duas matrizes.


Sistema de coordenadas

Quando se trabalha com gráficos, como neste projeto, costuma usar-se como origem do sistema de coordenadas o topo esquerdo da imagem com se está a trabalhar. Ou seja, usa-se um sistema em que o eixo dos xs cresce para a esquerda, como no sistema cartesiano, mas o eixo dos ys cresce para baixo, ao contrário do sistema cartesiano.

O seguinte diagrama ajuda a tirar dúvidas:



O interpretador

O nosso interpretador de comandos possui dois registos de trabalho, A e B, onde são guardadas duas imagens. Para informar o utilizador, o interpretador está constantemente a mostrar as dimensões das imagens guardadas nos registos. Quando algum dos registos está vazio, essa situação é indicada usando "?". Eis um exemplo, no qual o registo A tem uma imagem mas o registo B não:

Os registos A e B são geridos da seguinte forma:


Comandos

Agora apresentamos os comandos que o seu programa deve implementar, aproximadamente por ordem de dificuldade crescente. Há 18 comandos, alguns dos quais com variantes. 5 desses comandos já foram implementados no código inicial oferecido. Portanto, falta implementar 13 comandos.

O utilizador incida cada comando através duma letra que pode ser escrita em maiúsculas ou em minúsculas, não importa. No caso dos comandos com variantes, usa-se uma segunda letra, encostada à primeira, para indicar a variante.

Eis um pequeno extrato duma sessão de trabalho com o interpretador:

Vários comandos obrigam a considerar o centro da imagem. O melhor é eliminar desde já qualquer hipótese de ambiguidade: consideramos que o centro duma imagem de tamanho n se encontra nas coordenadas int2_metade(n).

Outro aspeto importante que se aplica a todos os comandos: Sempre que houver lugar a arredondamento de valores positivos, esse arredondamento será feito para baixo.

Segue-se a apresentação dos vários comandos:



Recomendações

Leia este enunciado com atenção, mais do que uma vez ao longo do desenvolvimento do programa, e releia ainda no final para ver se ficou a faltar alguma coisa. É necessário respeitar o que se pede no enunciado. Na verdade, este projeto avalia duas capacidades diferentes:

Escreva o seu programa incrementalmente, testando sempre cada função e cada comando novo, por forma a garantir que o programa está sempre a funcionar, mesmo que ainda não faça tudo o que pretende. Saiba que é terrível perder o controlo durante a escrita dum programa grande. Nessa situação, por vezes é preciso recomeçar do início.

Comece por fazer os comandos mais simples, ou seja os primeiros da lista.

Para obter um programa legível vai precisar de criar novas funções, por exemplo ao nível do processamento de píxeis, mas não só. Se não fizer isso, as funções que implementam os comandos mais sofisticados ficarão demasiado complicadas, difíceis de perceber, e logo valerão menos pontos em termos de classificação.

Teste muito bem o seu programa, inspirando-se nos ensinamentos do início da aula teórica 4. Nos anos anteriores, tem-se verificado que os grupos com melhor nota são os que exercem o seu sentido crítico e investem algum tempo a criar testes para tentar fazer falhar o programa. Por outro lado, quem não testa os programas por vezes perde imensa cotação com distrações, como a troca dum sinal ou algo do género. (Algumas dessas distrações seriam perdoadas num teste, mas não no projeto. É mesmo um objetivo assumido evitar dar notas altas a quem não testar bem o programa.)

No caso de você ter um erro difícil de corrigir, use as técnicas que foram discutidas no início da aula teórica 9. (Claro, também pode pedir alguma ajuda a um professor.)

Para fazer o trabalho completo (para 20 valores) não chega o tempo das aulas práticas. Precisará de trabalhar em casa tanto tempo como nas aulas práticas. No entanto, de forma geral, o tempo das aulas práticas é mais do que suficiente para obter uma nota positiva baixa.

O fórum de IP-B é o local mais indicado para colocar dúvidas sobre a interpretação do enunciado. No fórum também podem ser colocadas dúvidas sobre aspetos técnicos da realização do trabalho desde que isso não envolva divulgar publicamente partes do seu código. Só pode mostrar o seu código aos professores.

Este projeto é para ser resolvido em grupos de dois alunos. Os grupos podem podem discutir ideias gerais, inclusivamente publicamente no fórum, mas devem manter uma certa distância entre si, não podendo partilhar ideias absolutamente detalhadas nem ler código mútuo. Quando um grupo escreve um programa inspirando-se fortemente no trabalho de outro grupo, isso é normalmente fácil de detetar pelos docentes ou pelo sistema automático de deteção de cópias do DI. No caso de ser o sistema de deteção a chamar a atenção, depois um professor analisa o caso e toma uma decisão. O sistema de deteção é muito sofisticado e até serviu de base a uma tese de doutoramento.



Requisitos técnicos


O comentário inicial

No ficheiro "imagens.c" você é obrigado a incluir um comentário inicial curto, que convém que não exceda a meia página, mas pode ser mais pequeno.

O comentário deve conter o seguinte:

  1. Identificação dos autores do trabalho: nome e número dos alunos.
  2. Indicação de qual foi o docente das aulas práticas.
  3. Quais as partes do enunciado que não foram realizadas.
  4. Se achar mesmo necessário, pode alertar o avaliador para algum aspeto da implementação que você ache importante mas pense que o avaliador possa não detetar ou perceber.

Modo de realização

O trabalho é para ser realizado por grupos de dois alunos, em princípio com os dois alunos pertencentes ao mesmo turno prático. Não é necessário efetuar o registo prévio de cada grupo; basta que na submissão final apareça a identificação de dois alunos pertencentes ao mesmo turno prático.

Em algumas situações raras, que têm de ser previamente autorizadas por AMD e requerem uma boa justificação, poderá existir algum grupo com apenas um aluno.

Não se proíbem grupos com dois alunos de turnos diferentes, mas o problema é que isso faz com que mais alunos sejam trazidos para turnos já demasiado cheios. Os grupos com dois alunos de turnos diferente têm de aceitar o seguinte: sair de livre vontade duma aula prática demasiado cheia - têm prioridade para ficar na sala os grupos em que ambos os alunos estão inscritos nesse turno prático. (Os turnos foram dimensionados para 24 alunos. A partir de 24 alunos a qualidade das aulas piora muito e todos os alunos presentes ficam a perder.)

Não está previsto um trabalho ser entregue por três ou mais alunos. É completamente proibido. O trabalho nem sequer é corrigido.

Se, num grupo de dois alunos, algum desistir a meio do projeto, a situação terá de ser discutida pessoalmente com AMD para se encontrar uma solução. Contudo, a solução nunca será formar um grupo de três ou mais alunos.

Para aumentar a produtividade, algumas partes podem ser implementadas em paralelo pelos dois elementos de um grupo, se cada elemento tiver um computador disponível. Por exemplo, cada elemento do grupo poderá trabalhar na sua própria casa.

O trabalho visa aplicar os métodos e as técnicas ensinadas na cadeira. Assim, durante a execução do trabalho é conveniente consultar as notas de apoio deste ano e os exercícios das aulas práticas.

Os diferentes grupos são incentivados a discutir entre si aspetos do trabalho (inclusivamente no fórum da cadeira). Mas os grupos não podem partilhar código nem mesmo ler o código uns dos outros. A escrita de código exige muito esforço intelectual, mas só com esforço se consegue evoluir. Como sabe, fraude é punida com a exclusão da cadeira (exclusão tanto de quem copiou como de quem possibilitou a cópia, de propósito ou sem querer). Por isso, nunca deixe o seu trabalho, mesmo que ainda incompleto, no disco rígido de um computador dos laboratórios, numa mesa de trabalho (em papel ou numa caneta USB), em sites públicos da Net, etc. Os trabalhos serão submetidos a um sistema automático de deteção de cópias e quase todos os anos são detetados trabalhos com partes copiadas (com a cópia disfarçada), mas não queira que isso aconteça ao seu grupo.

Antes de submeter o seu programa no concurso final do Mooshak, releia este enunciado para ver se se esqueceu de alguma coisa. Compile e teste de novo o programa, pois pequenas alterações de última hora podem ter introduzido erros.


Regras de submissão

Concurso de teste - Testar o seu programa no Mooshak

Este concurso - IP-B Projeto Teste 2017/18 - serve para você ver e perceber como é que o Mooshak reage ao seu programa e também para o ajudar detetar algum possível erro de entendimento de alguma parte do enunciado.

Mas atenção! Trata-se duma ajuda muito limitada. Os testes são fracos, pois não abrangem todos os comandos e baseiam-se apenas na imagem "frutos.png". Há inúmeros potenciais erros que não são apanhados por estes testes.

Porque é que não são fornecidos testes mais completos? Porque a conceção dos testes faz parte da tarefa da programação, ou seja, é trabalho seu.

Neste concurso, você pode submeter as vezes que quiser. Tudo o que submeter não conta para a nota. A entrega oficial do projeto será feita noutro concurso.

O concurso de teste tem 9 testes, cada um dos quais valendo 1 ponto. Portanto, 9 pontos é a pontuação máxima e corresponde a um Accepted. Mas repare que as regras de avaliação não obrigam a ter um Accepted para o projeto ser corrigido.

São testados os seguintes comandos: Q, N, D, X (XH e XV), S, G (GH, GV e GC), P, I, F.

Este concurso de teste vai permanecer sempre aberto, sem limite de tempo.

Concurso final - Entrega oficial definitiva do trabalho através do Mooshak

Ao contrário do concurso de teste, o concurso final só permite um único Accepted por grupo. A partir do momento em que se obtém um Accepted, já não é possível submeter novas versões.

O concurso final chama-se: IP-B Submissão Final 2017/18. Não serve para fazer experiências e só aceita uma única submissão por grupo. Isso significa que a submissão neste concurso é um ato irreversível e de grande responsabilidade.

Submeta só quando tiver a certeza de que não vai alterar mais o seu programa. Se ainda não tiver a certeza, continue a usar o concurso de teste.

Submeter no concurso final significa dizer formalmente: "Esta é a versão que nós queremos que os professores avaliem!"

O concurso final só tem um teste, que inclui a execução dos comandos "gradiente horizontal" e "gradiente vertical".

Só serão corrigidos os trabalhos que: (1) sejam submetidos no concurso final; (2) não tenham erros de compilação; (3) cumpram as regras da secção "Modo de realização".

Não se esqueça de fazer o que se pede na secção "O comentário inicial", um pouco mais atrás.


Avaliação

Mooshak

A maior parte da nota do projeto - 16 valores - é atribuída pelo Mooshak ao funcionamento do programa, mesmo antes dos docentes lerem o código do programa.

Os restantes 4 valores têm a ver com aspetos relacionados com a qualidade do código. Em princípio, os aspetos de qualidade do código que vão ser considerados são:

Considerações

Apesar de o projeto ser de grupo, cada aluno, a título individual, tem a responsabilidade de responder por todo o trabalho. É indispensável que os dois membros de cada grupo o desenvolvam efetivamente, para com isso poderem evoluir na escrita de programas. Algum aluno que seja mais entusiasta deverá também deixar o colega comandar a realização duma parte do trabalho.

Haverá discussões dos projetos, mas será normal os docentes entenderem dispensar muitos alunos da discussão.


Final

Bom trabalho! Esperamos que goste.