Grauwerte skalieren

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Grauwerte skalieren

Beitrag von nici »

Hallo,

ich möchte gern ein Schwarz-Weiss Bild in den Grauwerten skalieren. Ich weiss nur dass 2Pi = weisst ist und dass 0=scharz sein soll. Aber wie ich das anfangen soll weiss nicht, kann mir jemand einen Vorschlag machen, danke.

lg

nici
Hmm mir fällt nichts ein ^^
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Die Frage versteh ich gerade nicht....du hast ein schwarz weiss Pic. UN d wie/durch was willst du skallieren? Bzw was willst du wirklich machen? Schwellwert Op oder sowas?
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

Ich muss das Bild ( eine Phasenplatte, schwarz-weiss bild) heller und dunkler machen können, so dass man dann bestimmte Punkte besser sehen soll. Wörtlich von meinem Chef "Grau-Werte skalieren".

lg

nici
Hmm mir fällt nichts ein ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Gib das Bild in ein QImage. lies jedes Pixel (evtl. einer Selektion) mit QImage::pixel() ein. Dann musst du aus dem Pixel rot, grün, blau auslesen und entsprechend erhöhen oder erniedrigen (da es ja scheinbar S/W ist, reicht es sogar, nur z.B. blau auszulesen, da bei nem grauen Pixel eigenlich alle 3 Farbkanäle gleich hoch sein sollten).
Nun bastel dir aus den errechneten Werten ein neues QRgb zusammen und setz es im Image mittels QImage::setPixel().

Auf dem selben Weg kannst du auch noch den Kontrast erhöhen, erniedrigen.

Grüße
Franz
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

also für die Rgb-Werte hab ich

Code: Alles auswählen

QVector<QRgb> imgAsVector = i16ImageToRGB(img);
	uchar * data = reinterpret_cast<uchar *>(imgAsVector.data());
	qDebug() << "data : " << data << endl ;
	Q_ASSERT(!data);
	if(!data) { 
		qDebug() << "Phase plate image is invalid.";
		return;
	}
	_mPix = QPixmap::fromImage(QImage(data, img.width(), img.height(),QImage::Format_RGB32 ));
	imageLabel->setPixmap(_mPix) ;
und für die skalierung der größe hab ich

Code: Alles auswählen

void TabEins::resizeImage(int i){
	int newWidth =  _mPix.width()*i/100;
    int newHeight = _mPix.height()*i/100;
	imageLabel->setPixmap(_mPix.scaled(newWidth,newHeight));		
}
Hmm mir fällt nichts ein ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

nici hat geschrieben:also für die Rgb-Werte hab ich

Code: Alles auswählen

QVector<QRgb> imgAsVector = i16ImageToRGB(img);
	uchar * data = reinterpret_cast<uchar *>(imgAsVector.data());
	qDebug() << "data : " << data << endl ;
	Q_ASSERT(!data);
	if(!data) { 
		qDebug() << "Phase plate image is invalid.";
		return;
	}
	_mPix = QPixmap::fromImage(QImage(data, img.width(), img.height(),QImage::Format_RGB32 ));
	imageLabel->setPixmap(_mPix) ;
Nach der ersten Zeile musst du doch dann nur über alle Vector-Elemente iterieren und entsprechend dem o.g. "Algorithmus" die Werte verändern.
Schreib das alles in nen Slot, ala "changeBrightness(int val)", wenn val <0 mach dunkler, sonst heller.
Dann connectest du das mit z.B. ner Spinbox (mit passendem Range, z.B (-100, 100, default 0). fertig.
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

das mit dem Slot funktioniert nicht, da der Code schon in einer Methode drin ist.
Hmm mir fällt nichts ein ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

nici hat geschrieben:das mit dem Slot funktioniert nicht, da der Code schon in einer Methode drin ist.
Eigentlich sollte ich jetzt sagen "kein Kommentar" :D

Du musst halt bissl umbasteln.
WIe wäre es hiermit?

Code: Alles auswählen

bool PlateEditor::setImageFromVector(const QVector<QRgb>& imgData)
{
    uchar * data = reinterpret_cast<uchar *>(imgData.data());
    qDebug() << "data : " << data << endl ;
    Q_ASSERT(!data);
    if(!data) {
        qDebug() << "Phase plate image is invalid.";
        return false;
    }
    _mPix = QPixmap::fromImage(QImage(data, img.width(), 
                                                              img.height(),
                                                              QImage::Format_RGB32 )
                                                 );
    imageLabel->setPixmap(_mPix) ;
    return true;
}

// slot
void PlateEditor::changeBrightness(int val)
{
    QVector<QRgb> imgAsVector = i16ImageToRGB(img);
    // hier code zum Manipulieren der Hellligkeit
    setImageFromVector( imgAsVector );
}

void PlateEditor::resetImage()
{
    QVector<QRgb> imgAsVector = i16ImageToRGB(img); 
    setImageFromVector( imgAsVector );
}
Und es geht vllt. sogar noch schöner. Aber ich kenn deine restliche Klasse nicht.
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

cool danke dir.
Es kommt nur ein Fehler:

error: reinterpret_cast from type 'const unsigned int*' to type 'uchar*' casts away constness

muss ich noch was includieren??

lg

nici
Hmm mir fällt nichts ein ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Versuch die Fehlermeldung selbst zu verstehen. Includieren musst du nix.

So als kleiner Tip:
1) uchar* kannst du verändern
2) const unsigned int* kannst du NICHT verändern (wegen dem const).
Dein cast will jetzt 2 nach 1 überführen. Und genau das geht nicht.

Entweder nimmst du aus der Methodendeklaration das const vor dem QVector<QRgb> weg, oder du castest data() nach const uchar*.

Da du deine Daten in setImageFromVector eh nimmer verändern willst, bietet sich doch letzteres an.

Grüße
Franz
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

also irgendwie beissen sich deine Methoden mit dem Rest meiner Klasse:

Code: Alles auswählen

void TabEins::resizeImage(int i){
	int newWidth =  _mPix.width()*i/100;
    int newHeight = _mPix.height()*i/100;
	imageLabel->setPixmap(_mPix.scaled(newWidth,newHeight));		
}

void TabEins::savePic()
 {   
 	QString filter = "Images (*.png;; *.xpm;; *.jpg;; *.jpeg;; *.bmp;; *.tiff;; *.xbm)";
	QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"/home/nurc/untitled.png",filter);
	QString suf = QFileInfo(fileName).suffix();
	//bool QImageIOHandler::canRead() const;
	if(!fileName.isEmpty()){		
		if( filter.contains( suf ) ){
			_mPix.toImage().save(fileName);
		}else{
			QMessageBox::warning(this, "Warnung", "Falsche Dateiendung");
		}	
	}  	      
 }; 

void TabEins::loadPic() 
 { 	
	QString fileName = QFileDialog::getOpenFileName(this, "Open File", "/home/nurc",("Images(*.tiff *.png *.gif *.jpg *.jpeg *.bmp *.tiff *.xbm *.xpm)"));												  
		QImage file(fileName);
		
		if(!fileName.isEmpty()){
		if(file.isNull()) { 
			qWarning()<<"Fehler beim oeffnen der Datei!";
		}	qWarning() << "ok";
		_mPix = QPixmap::fromImage(file);
		imageLabel->setPixmap(_mPix);
	}	
 };
 

void TabEins::drawPhasePlate(bool checked)
{
	int imgSize = 256 ;
	double dImgSize = static_cast<double>(imgSize) ; 
	Aberration aber ;
	
	double highTension = _aberrTable->getHighTension();
	double apertureAngle = _aberrTable->getApertureAngle(); 
	
	I16Image::Pixel maxPixVal = std::numeric_limits<I16Image::Pixel>::max();
	double lambda = Physics::AccVoltageToWavelength(highTension);
        I16Image img(imgSize, imgSize) ;

	int ix ;
	int iy ;
	for(ix=0; ix< imgSize; ix++){
	   for(iy=0; iy < imgSize; iy++){ 
		 
	         double ax = ((static_cast<double>(ix)*2.0/(dImgSize-1.0)) - 1.0)*apertureAngle ; 
	         double ay = -((static_cast<double>(iy)*2.0/(dImgSize-1.0)) - 1.0)*apertureAngle ; 
	         double negChiDurchLambda = -TEMTableauAnalysis::opticalPathLength(aber, ax, ay) / lambda ;
	         double negChiDurchLambdaWrapped = (negChiDurchLambda - static_cast<double>(static_cast<int>(negChiDurchLambda)) ) ;
	         if(negChiDurchLambdaWrapped < 0.0){
	              negChiDurchLambdaWrapped += 1.00 ;
	         }
	         // Testen: negChiDurchLambdaWrapped muss im Intervall [0.0, 1.0)     
	         double justForControl = (negChiDurchLambda - negChiDurchLambdaWrapped) ; // sollte bis auf Rundungsfehler 
                                                                                          // ganzzahlig sein
	         img(ix, iy) = static_cast<int16>(negChiDurchLambdaWrapped * static_cast<double>(maxPixVal) + 0.5);

	    }
	} 
	
 	QVector<QRgb> imgAsVector = i16ImageToRGB(img);
 		uchar * data = reinterpret_cast<uchar *>(imgAsVector.data());
 	qDebug() << "data : " << data << endl ;
 	Q_ASSERT(!data);
 	if(!data) { 
 		qDebug() << "Phase plate image is invalid.";
 		return;
 	}
 	_mPix = QPixmap::fromImage(QImage(data, img.width(), img.height(),QImage::Format_RGB32 ));
 	imageLabel->setPixmap(_mPix) ;
}

// Bild fuellen 
void TabEins::fillPicRamp(I16Image & img)
{
	for(int ix = 0 ; ix < img.width() ; ix++) {
		for(int iy = 0 ; iy < img.height() ; iy++) {
			img.value(ix, iy) = static_cast<int16>(ix);
		}
	}  
}

QVector<QRgb>
TabEins::i16ImageToRGB(const I16Image &img) const {
	QVector<QRgb> rgbData;
	rgbData.reserve(img.width()*img.height());
	I16Image::Pixel maxPixVal = std::numeric_limits<I16Image::Pixel>::max();
	uint8 maxByteVal = std::numeric_limits<uint8>::max() ;
	double scale = static_cast<double>(maxByteVal)/static_cast<double>(maxPixVal);
	//double scale static_cast<double>()/static_cast<double>()
	for(int iy = 0 ; iy < img.height() ; iy++) {
		for(int ix = 0 ; ix < img.width() ; ix++) {
			double imgValue = img.value(ix, iy) ;
			uint8 greyValue = static_cast<uint8>(scale * imgValue + 0.5);
			QRgb rgb = qRgb(greyValue, greyValue, greyValue);
			rgbData.append(rgb);
		}
	}
	return rgbData;
}

lg

nici
Hmm mir fällt nichts ein ^^
erpheus
Beiträge: 46
Registriert: 18. November 2008 11:55
Wohnort: Stuttgart

Beitrag von erpheus »

Hm könntest Du genauer schreiben inwiefern sich das beißt. Ich kann in deiner geposteten Klasse keinen Bezug zur zum vorigen Poste herstellen.

Die Methode

Code: Alles auswählen

 bool PlateEditor::setImageFromVector(const QVector<QRgb>& imgData) 
steht ja in der Klasse PlateEditor. Gepostet hast Du Funktionen der Klasse TabEins. In dieser kann ich keinen Funktionsaufruf oder ähnliches finden.

Also wo hakt es da?

franzf hat ja Änderungen innerhalb der Methode vorgeschalgen vor allem diese hier:
oder du castest data() nach const uchar*
Was geschieht wenn Du dies tust? Fehlermeldungen usw.

Find das Thema übrigens echt interessant.
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

das Problem ist, dass ich keine Klasse PlateEditor habe und es dann halt in TabEins umgewandelt habe. Oder verstehe ich da wieder estwas komplett falsch??

lg

nici
Hmm mir fällt nichts ein ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Und worin besteht das Problem dann jetzt?
Es ist klar, dass du die Klasse an deine Namensgebug anpassen musst, also PlateEditor in TabEins (Eigentlich ein recht nichtssagender Klaasenname ;)) umbenennen.

Hast du jetzt Kompilierfehler, Probleme das in deine Klasse eizufügen, oder sonstwas?
Antworten