Negativfilter in c++



  • Hallo,

    ich hab ein Problem. Und zwar soll ich einen Negativfilter als Übung in meinem Studium programmieren. Es soll von einem Bild ein Negativ erstellt werden.
    Kann mir jemand helfen? Ich hab keine Ahnung wie ich das machen soll.
    Danke.

    Gruß
    schmitti81



  • Was sagt denn das www dazu?

    Was sollst du genau machen? Ein Negativbild eines Schwarz-Weiß Bildes ist einfach. Von einem Graustufenbild auch.



  • Im www hab ich nix passendes gefunden.

    Aus einem s/w-Bild soll ein negativ gebildet werden. Ich muss doch irgendwie die Werte ändern, oder?
    Ein Code-Beispiel wär nicht schlecht.
    DANKE!

    Gruß
    schmitti81



  • schmitti81 schrieb:

    Ein Code-Beispiel wär nicht schlecht.

    Mehr Infos auch nicht ... in welchem Format liegt denn das Bild vor bzw. welche Eingabe erhält das Programm?



  • if(pixel == white) pixel = black;
    if(pixel == black) pixel = white;

    bzw. wenn bool für S/W verwendet wird gehts noch einfacher mit pixel = !pixel.

    Das solltest du aber selbst auch schon wissen, wie genau das abzuspeichern ist kommt ganz auf das verwendete Format (bmp, jpg, gif, png, etc.) an.

    MfG SideWinder



  • SideWinder schrieb:

    if(pixel == white) pixel = black;
    if(pixel == black) pixel = white;

    Das geht auch kürzer:

    pixel = white;
    

    😃



  • *rofl* 🤡 👍



  • Ok, else if :p

    MfG SideWinder



  • SideWinder schrieb:

    Ok, else if :p

    Ja, das dürfte schneller sein 😃 👍

    Aber ich denk mal dass die Aufgabenstellung eher nach

    pixel = pixelmax - pixel;
    

    verlangt.



  • @finix: Genau so sollte es sein.
    Danke auch dem Rest für die Hilfe.
    Ich werd das dann mal an einem konkreten Beispiel testen.

    Gruß
    schmitti81



  • Irgendwie klappt es innerhalb des Programms doch nicht. Ich muss das in eine vorhandenen Datei einbinden.
    Aber irgendwie komm ich nicht ganz klar.

    Kann mal jemand ein Programm-Beispiel schreiben, das ein .tif- oder ein .bmp-Bild
    (s/w) invertiert, also ein Negativbild daraus macht.
    Das wär sehr nett. Dann könnt ich das einfach versuchen umzusetzen.
    Vielen , vielen Dank.

    Gruß
    schmitti81



  • Zeig mal deinen bisherigen Code, wir sidn hier nicht für Hausübungen zuständig sondern helfen bei bestimmten Problemen 🙂

    MfG SideWinder



  • Ich habe jetzt keinen Code zur Hand, evtl. hilft Dir aber folgende Einführung: http://www.runicsoft.com/bmp.php

    Ansonsten solltest Du mal in die (Online-)MSDN schauen, in der das BMP-Format detailliert beschrieben ist.



  • ByteImage.h:

    // ByteImage.h: Schnittstelle für die Klasse ByteImage.
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(_BYTEIMAGE_H_)
    #define _BYTEIMAGE_H_
    
    #define MAX_COLOR 256
    
    #include <stdlib.h>
    
    class ByteImage  
    {
    public:
    
    	ByteImage();
    	ByteImage(unsigned int zeilen, unsigned int spalten);
    	ByteImage::ByteImage(char* fName);
    	virtual ~ByteImage();
    
    	inline unsigned int GetNRows() { return _NRows; }
    	inline unsigned int GetNCols() { return _NCols; }
    
    	inline void SetPixel(unsigned int row, unsigned int col, unsigned char value)
    	{
    		if ((row<_NRows) && (col<_NCols)) buffer[row*_NCols+col] = value;
    	}
    
    	inline void SetPixelFast(unsigned int row, unsigned int col, unsigned char value) 
    	{ 
    		buffer[row*_NCols+col] = value; 
    	}
    
    	inline unsigned char GetPixel(unsigned int row, unsigned int col)
    	{
    		if ((row<_NRows) && (col<_NCols)) return buffer[row*_NCols+col];
    		else 
    		{ 
    			// Fehler wird hier nicht abgefangen
    			return 0;
    		}
    	}
    
    	inline unsigned char GetPixelFast(unsigned int row, unsigned int col) 
    	{ 
    		return buffer[row*_NCols+col]; 
    	}
    
    	void Clear();
    	void Clear(unsigned char value);
    	bool Median(ByteImage*);
    	bool invert(ByteImage*);
    	void sortFeld(unsigned char*);
    
    	int Save(char* name);
    
    private:
    	unsigned int _NRows;
    	unsigned int _NCols;
    
    	unsigned char* buffer;
    };
    
    #endif // !defined(_BYTEIMAGE_H_)
    

    ByteImage.cpp:

    // ByteImage.cpp: Implementierung der Klasse ByteImage.
    //
    //////////////////////////////////////////////////////////////////////
    
    #include <math.h>
    #include <string.h>
    
    #include "ByteImage.h"
    
    #include "FreeImage.h"
    
    //////////////////////////////////////////////////////////////////////
    // Konstruktion/Destruktion
    //////////////////////////////////////////////////////////////////////
    unsigned char Grauwert[MAX_COLOR];  
    
    ByteImage::ByteImage()
    {
    	buffer = NULL;
    	_NRows = _NCols = 0;
    }
    
    ByteImage::ByteImage(unsigned int nRows, unsigned int nCols)
    {
    	buffer = new unsigned char[nRows*nCols];
    	if (buffer != NULL)
    	{
    		_NRows = nRows;
    		_NCols = nCols;
    		this->Clear();
    	}
    	else
    	{
    		_NRows = _NCols = 0;
    	}
    }
    
    ByteImage::ByteImage(char* fName)
    {
    	FIBITMAP *image = NULL;
    
    	buffer = NULL;
    	_NRows = _NCols = 0;
    
    	FREE_IMAGE_FORMAT fif;
    
    	fif = FreeImage_GetFIFFromFilename(fName);
    	if (fif != FIF_UNKNOWN) image = FreeImage_Load(fif, fName, 0);
    
    	if (image)
    	{
    		_NCols = FreeImage_GetWidth(image);
    		_NRows = FreeImage_GetHeight(image);
    
    		buffer = new unsigned char[_NRows*_NCols];
    		if (buffer == NULL)
    		{
    			_NRows = _NCols = 0;
    		}
    		else
    		{
    			FreeImage_ConvertToRawBits(buffer, image, _NCols, 8,  0, 0, 0, FALSE);
    		}
    		FreeImage_Unload(image);
    	}
    }
    
    ByteImage::~ByteImage()
    {
    	if (buffer) 
    	{
    		delete buffer;
    		buffer = NULL;
    		_NRows = _NCols = 0;
    	}
    }
    
    void ByteImage::Clear()
    {
    	if (!buffer) return;
    
    	unsigned char* p = buffer + _NRows*_NCols-1;
    
    	while (p>=buffer) *(p--) = 0;
    
    }
    
    void ByteImage::Clear(unsigned char value)
    {
    	if (!buffer) return;
    
    	unsigned char* p = buffer + _NRows*_NCols-1;
    
    	while (p>=buffer) *(p--) = value;
    
    }
    
    int ByteImage::Save(char *name)
    {
    	FREE_IMAGE_FORMAT fif;
    
    	FIBITMAP* bitmap = FreeImage_Allocate(_NRows, _NCols, 8);
    
    	if (!bitmap) return -1;
    
    	fif = FreeImage_GetFIFFromFilename(name);
    	if (fif == FIF_UNKNOWN) 
    	{
    		FreeImage_Unload(bitmap);
    		return -1;
    	}
    
    	bitmap = FreeImage_ConvertFromRawBits(buffer, _NCols, _NRows, _NCols, 8,  0, 0, 0, FALSE);
    	RGBQUAD *lut = FreeImage_GetPalette(bitmap);
    
    	for(int i=0; i<256; i++)
    	{
    		lut[i].rgbRed   = i;
    		lut[i].rgbGreen = i;
    		lut[i].rgbBlue  = i;
    	}
    
    	FreeImage_Save(fif, bitmap, name, 0);
    	FreeImage_Unload(bitmap);
    
    	return 0;
    }
    
    bool ByteImage::Median(ByteImage* TMPImage){
    
    	unsigned char GWA[9] = {0};
    
    	for(unsigned int cols = 0; cols < this->_NCols; cols++){
    		for(unsigned int rows = 0; rows < this->_NRows; rows++){
    
    		//X**
    		GWA[0] = this->GetPixel(rows - 1, cols - 1);
    		GWA[3] = this->GetPixel(rows , cols - 1);
    		GWA[6] = this->GetPixel(rows + 1, cols -1);
    
    		//*X*
    		GWA[1] = this->GetPixel(rows - 1, cols);
    		GWA[4] = this->GetPixel(rows, cols);
    		GWA[7] = this->GetPixel(rows + 1, cols);
    
    		//**X
    		GWA[2] = this->GetPixel(rows  -1 , cols + 1);
    		GWA[5] = this->GetPixel(rows, cols + 1);
    		GWA[8] = this->GetPixel(rows + 1, cols + 1);
    
    		this->sortFeld(GWA);
    
    		TMPImage->SetPixel(rows, cols, GWA[5]);
    
    		}
    	}
    
    	return true;
    }
    
    /*------------------------------------------------------------------------------
    Mein Programm
    ------------------------------------------------------------------------------*/
    
    bool ByteImage::invert(ByteImage* TMPImage){
    
    	SetPixel = MAX_COLOR - GetPixel;
    }
    
    void ByteImage::sortFeld(unsigned char* feld){
    	int lauf, i;
    	unsigned char dummy;
    
    	for (lauf=1; lauf< 9; lauf++) {
    		for (i=0; i< 8; i++)
    			if (feld[i] > feld[i+1]){ // Dreieckstausch
    				dummy=feld[i];
    				feld[i]=feld[i+1];
    				feld[i+1]=dummy;
    			}
        }
    }
    

    Test1.cpp:

    #include <stdio.h>
    
    #include "ByteImage.h"
    
    #define SIZE 256
    
    void main(int arg, char** argc){
    
    	ByteImage* Image1 = new ByteImage("monkewy.tif");
    
    	unsigned int cols = Image1->GetNCols();
    	unsigned int rows = Image1->GetNRows();
    
    	ByteImage* Ausgabe = new ByteImage(rows ,cols);
    
    	Image1->Median(Ausgabe);
    
    	Ausgabe->Save("michi.bmp");
    
    	unsigned char cocomo[SIZE][SIZE] = {0};
    	ByteImage* CocoImg = new ByteImage(SIZE, SIZE);
    
    	unsigned int Crows = 0, Ccols =0;
    
    	for(Crows = 0; Crows < rows; Crows++){
    		for(Ccols = 0; Ccols < cols; Ccols++){
    			cocomo[Image1->GetPixel(Crows, Ccols)][Image1->GetPixel(Crows, Ccols +1)]++;
    			}
    		}
    
    	for(Crows = 0; Crows < 255; Crows++){
    		for(Ccols = 0; Ccols < 255; Ccols++){
    			CocoImg->SetPixel(Crows, Ccols, cocomo[Crows][Ccols]);
    			}
    		}
    
    	CocoImg->Save("coco.bmp");
    
    	}
    

    Ein Medianfilter ist schon implmentiert. Das hab ich aber mit Kommilitonen gemacht. Das ist aber schon ein Jahr her. Jetzt wollte ich zum Üben den Negativfilter implementieren. Aber irgendwie komm ich grad nicht weiter.

    Verwendet wird die FreeImage-Bibliothek.

    Danke für eure Hilfe.

    Gruß
    schmitti81



  • Na dann hast du es doch ...

    Du hast ne Methode für GetPixel, womit du auf jeden Pixel zugreifen kannst.
    Wenn es nach dem Schema 'pixel = maxpixel - pixel' sein soll, gehst du halt mit einer (oder zwei verschachtelten) for-Schleife(n) über dein Bild und wandelst jeden Pixel nach obiger Formel ab.

    Wo liegt da nun das Problem?

    edit:
    Und da deine Klasse sowieso nur 8bit-Graustufenbild unterstützt, machst es mit dem Wert 255 für maxpixel:

    pixel = 255 - pixel;
    


  • Ist das nicht einfach pixel = Weiß - pixel oder auch noch pixel ^= Weiß? (Weiß = 0xFF und 0x00 = Schwarz)



  • Du musst jeden Pixel invertieren.

    bool ByteImage::invert( ByteImage* TMPImage )
    {
      // for each row
        // for each col
          SetPixel(row, col, MAX_COLOR - GetPixel(row, col);
    }
    


  • finix schrieb:

    Du musst jeden Pixel invertieren.

    Das ist jetzt aber nicht dein Ernst, darauf hinzuweisen? 😉



  • p.s. die Image-Klasse scheint kaputt zu sein. Wie stellst du schwarz dar?



  • DarthZiu schrieb:

    finix schrieb:

    Du musst jeden Pixel invertieren.

    Das ist jetzt aber nicht dein Ernst, darauf hinzuweisen? 😉

    Doch:

    schmitti81 schrieb:

    // ByteImage.cpp, line 168
    /*------------------------------------------------------------------------------
    Mein Programm
    ------------------------------------------------------------------------------*/
    
    bool ByteImage::invert(ByteImage* TMPImage){
    
        SetPixel = MAX_COLOR - GetPixel;
    }
    


  • Das hatte ich gar nicht gesehen 😃
    Davon geht man eigentlich aus, dass das klar ist.

    Aber das

    finix schrieb:

    Doch:

    DarthZiu schrieb:

    // ByteImage.cpp, line 168
    /*------------------------------------------------------------------------------
    Mein Programm
    ------------------------------------------------------------------------------*/
    
    bool ByteImage::invert(ByteImage* TMPImage){
    
        SetPixel = MAX_COLOR - GetPixel;
    }
    

    hab ich nicht geschrieben 👍


Anmelden zum Antworten