Seite 1 von 1
Grauwerte skalieren
Verfasst: 22. Januar 2009 10:18
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
Verfasst: 22. Januar 2009 10:49
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?
Verfasst: 22. Januar 2009 10:51
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
Verfasst: 22. Januar 2009 11:04
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
Verfasst: 22. Januar 2009 11:10
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));
}
Verfasst: 22. Januar 2009 11:43
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.
Verfasst: 22. Januar 2009 12:20
von nici
das mit dem Slot funktioniert nicht, da der Code schon in einer Methode drin ist.
Verfasst: 22. Januar 2009 12:41
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"
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.
Verfasst: 22. Januar 2009 15:59
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
Verfasst: 23. Januar 2009 09:46
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
Verfasst: 23. Januar 2009 12:46
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
Verfasst: 23. Januar 2009 13:12
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.
Verfasst: 23. Januar 2009 13:15
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
Verfasst: 23. Januar 2009 17:10
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?