Primo commit di questa repo, è un bel progettino molto semplice da funzioni esplicative
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Ignoriamo le immagini
|
||||
*.png
|
||||
*.jpg
|
||||
*.ppm
|
||||
|
||||
# Ingoriamo i gli oggetti
|
||||
*.o
|
||||
*.x
|
||||
169
libImg.cpp
Normal file
169
libImg.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "libImg.h"
|
||||
|
||||
#define ASSERT_MSG(cond, msg) \
|
||||
do { if (!(cond)) { std::cerr << msg << std::endl; assert(cond); } } while (0)
|
||||
|
||||
// Salva un immagine in formato ppm P6 255
|
||||
bool save(const std::string& path, const image& matrix){
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
if(!f){
|
||||
std::cerr<<"Errore in save"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
int w = matrix[0].size();
|
||||
int h = matrix.size();
|
||||
f << "P6\n" << w << " " << h <<"\n255\n";
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for(int x = 0; x < w; x++){
|
||||
f.write(reinterpret_cast<const char*>(&matrix[y][x]), 3);
|
||||
}
|
||||
}
|
||||
|
||||
f.close();
|
||||
std::cout << "Fine salvato"<<std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Carica un immagine in formato ppm P6 255
|
||||
image load(const std::string& path, int& w, int& h){
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (!f) {
|
||||
std::cerr << "File non aperto" <<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
std::string magic;
|
||||
int val;
|
||||
f >> magic >> w >> h >> val;
|
||||
if(magic != "P6"){
|
||||
std::cerr << " Magic Sbagliato"<<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
if(val != 255){
|
||||
std::cerr << "Dimensione sbagliata dei colori "<<val<<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
|
||||
char sep;
|
||||
f.get(sep);
|
||||
|
||||
image matrix(h, std::vector<pixel>(w));
|
||||
for(int y = 0; y < h; y++){
|
||||
for(int x = 0; x < w; x++){
|
||||
f.read(reinterpret_cast<char*>(&matrix[y][x]), 3);
|
||||
if(f.gcount() != 3){
|
||||
std::cerr << "Distanza sbagliata" <<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
std::cerr << "Strano, mancano i pixel"<<std::endl;
|
||||
return errore;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
//Controlla l'ugualianza di 2 immagini
|
||||
// usa tutte le tecniche che sono standard + comparatore tra pixel
|
||||
bool images_equal(const image& a, const image& b) {
|
||||
if (a.size() != b.size() || a[0].size() != b[0].size()) return false;
|
||||
return a == b;
|
||||
}
|
||||
|
||||
//Genera rumore pseudo-casuale
|
||||
image randomImage(int w, int h){
|
||||
image matrix(h, std::vector<pixel>(w));
|
||||
|
||||
for(int y = 0; y < h; ++y){
|
||||
for(int x = 0; x < w; ++x){
|
||||
matrix[y][x] = {
|
||||
static_cast<unsigned char>(dist(rng)),
|
||||
static_cast<unsigned char>(dist(rng)),
|
||||
static_cast<unsigned char>(dist(rng))
|
||||
};
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
//converte un immagini in bianco e nero
|
||||
void BWimage(image &matrix, float lim){
|
||||
ASSERT_MSG(lim >= 0 && lim <= 1, "Il valore limite deve essere tra 0-1");
|
||||
|
||||
const pixel t = {
|
||||
static_cast<unsigned char>(lim*255),
|
||||
static_cast<unsigned char>(lim*255),
|
||||
static_cast<unsigned char>(lim*255)
|
||||
};
|
||||
|
||||
for(auto &i: matrix){
|
||||
for(auto &p: i){
|
||||
if(p >= t)
|
||||
p = {255,255,255};
|
||||
else
|
||||
p = {0, 0, 0};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//converte un immagine in scala di grigi
|
||||
void Grayimage(image &matrix){
|
||||
for(auto &i: matrix){
|
||||
for(auto &p: i){
|
||||
short s = (short) p.lum();
|
||||
p = {
|
||||
static_cast<unsigned char>(s),
|
||||
static_cast<unsigned char>(s),
|
||||
static_cast<unsigned char>(s)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long countW(image &matrix){
|
||||
int ans = 0;
|
||||
pixel max = {255, 255, 255};
|
||||
for(const auto &y:matrix){
|
||||
for(const auto &p: y){
|
||||
if(p == max)ans++;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
// +- 0,25 0,125 ...
|
||||
float BWAimage(image &matrix){
|
||||
image test;
|
||||
float lim = 0.5f;
|
||||
unsigned long long avg = matrix.size() * matrix[0].size() / 2;
|
||||
for(int i = 4; i <= 1<<6; i = i<<1){
|
||||
test = matrix;
|
||||
BWimage(test, lim);
|
||||
if(countW(test) < avg){
|
||||
lim -= 1.0f/i;
|
||||
}
|
||||
else{
|
||||
lim += 1.0f/i;
|
||||
}
|
||||
// Ez debug
|
||||
// std::cout<<"Il lim è: "<<lim<<std::endl;
|
||||
}
|
||||
matrix = test;
|
||||
return lim;
|
||||
}
|
||||
|
||||
void invertImage(image &matrix){
|
||||
for(auto &y:matrix){
|
||||
for(auto &p:y){
|
||||
p.r ^= 0xFF;
|
||||
p.g ^= 0xFF;
|
||||
p.b ^= 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
libImg.h
Normal file
40
libImg.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
struct pixel {
|
||||
unsigned char r, g, b;
|
||||
|
||||
bool operator==(const pixel& o) const { return r == o.r && g == o.g && b == o.b; }
|
||||
bool operator!=(const pixel& o) const { return !(*this == o); }
|
||||
bool operator>=(const pixel& o) const { return r - o.r + g - o.g + b - o.b > 0; }
|
||||
|
||||
float lum() const { return 0.2126f * r + 0.7152f * g + 0.0722f * b; }
|
||||
float lumNorm() const { return lum() / 255.0f; }
|
||||
};
|
||||
|
||||
using image = std::vector<std::vector<pixel>>;
|
||||
|
||||
//Variabili importanti
|
||||
inline std::mt19937 rng(10);
|
||||
inline std::uniform_int_distribution<unsigned int> dist(0, 255);
|
||||
inline image errore(1, std::vector<pixel>(1, {0, 0, 0}));
|
||||
|
||||
|
||||
bool save(const std::string& path, const image& matrix);
|
||||
image load(const std::string& path, int& w, int& h);
|
||||
|
||||
bool images_equal(const image& a, const image& b);
|
||||
unsigned long long countW(image &matrix);
|
||||
|
||||
image randomImage(int w, int h);
|
||||
void BWimage(image &matrix, float lim);
|
||||
void Grayimage(image &matrix);
|
||||
float BWAimage(image &matrix);
|
||||
void invertImage(image &matrix);
|
||||
void gaussianImage(image &matrix, int dim);
|
||||
50
main.cpp
Normal file
50
main.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// magick malenia.jpg -define ppm:format=raw test.ppm
|
||||
#include <bits/stdc++.h>
|
||||
#include "libImg.h"
|
||||
using namespace std;
|
||||
|
||||
const int WIDTH = 16 * 60;
|
||||
const int HEIGHT = 9 * 60;
|
||||
|
||||
int main () {
|
||||
/*
|
||||
image matrix = randomImage(WIDTH, HEIGHT);
|
||||
|
||||
//BWimage(matrix, 0.70);
|
||||
Grayimage(matrix);
|
||||
|
||||
if (!save("output.ppm", matrix, WIDTH, HEIGHT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int height, width;
|
||||
image caricato = load("output.ppm", width, height);
|
||||
|
||||
if(images_equal(matrix, caricato)){
|
||||
std::cout << "Cazzo funziona"<<endl;
|
||||
}else {
|
||||
std::cout << "MMMMMMMMM" <<endl;
|
||||
}
|
||||
|
||||
std::cout << "Matrice: " << HEIGHT << "x" << WIDTH << "\n";
|
||||
std::cout << "Caricato: " << height << "x" << width << "\n";
|
||||
std::cout << "Pixel [0][0] matrice: "
|
||||
<< (int)matrix[0][0].r << " " << (int)matrix[0][0].g << " " << (int)matrix[0][0].b << "\n";
|
||||
std::cout << "Pixel [0][0] caricato: "
|
||||
<< (int)caricato[0][0].r << " " << (int)caricato[0][0].g << " " << (int)caricato[0][0].b << "\n";
|
||||
*/
|
||||
int heightC, widthC;
|
||||
image carica = load("test.ppm", widthC, heightC);
|
||||
//Grayimage(carica);
|
||||
//float numerone = BWAimage(carica);
|
||||
//invertImage(carica);
|
||||
if(!save("testOutput.ppm", carica)){
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cout << "Numerone finale: " << numerone <<endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
makefile
Normal file
17
makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
# Makefile incredibile per il progrettone
|
||||
XX = g++
|
||||
CXXFLAGS = -O2 -Wall -Wextra -Wpedantic -Wshadow -D_GLIBCXX_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -Wshift-overflow=2
|
||||
|
||||
all: main.x
|
||||
|
||||
main.o: main.cpp
|
||||
$(CXX) main.cpp -c $(CXXFLAGS)
|
||||
|
||||
libImg.o: libImg.cpp
|
||||
$(CXX) libImg.cpp -c $(CXXFLAGS)
|
||||
|
||||
main.x: main.o libImg.o
|
||||
$(CXX) main.o libImg.o -o main.x $(CXXFLAGS)
|
||||
|
||||
run: main.x
|
||||
./main.x
|
||||
Reference in New Issue
Block a user