Пожалуйста, посмотрите на следующий код
using namespace cv;
double alpha = 1.6;
int beta = 50;
int i = 0;
IplImage* input_img = cvLoadImage("c:\\Moori.jpg", CV_LOAD_IMAGE_GRAYSCALE);
IplImage* imageGray = cvCreateImage(cvSize(input_img->width, input_img->height), IPL_DEPTH_8U, 1);
for( int y = 0; y < input_img->height; y++ )
{
for( int x = 0; x < input_img->width; x++ )
{
i = y * imageGray->width + x;
imageGray->imageData[i] = (alpha * input_img->imageData[i]) + beta;
}
}
cvNamedWindow("Image IplImage", 1);
cvShowImage("Image IplImage", imageGray);
waitKey();
cvReleaseImage(&imageGray);
cvReleaseImage(&input_img);
cvDestroyWindow("Image IplImage");
когда я запускаю этот код, он показывает изображение с большим количеством темных пикселей.
Но когда я запускаю код, который доступен по адресу:
http://docs.opencv.org/doc/tutorials/core/basic_linear_transform/basic_linear_transform.html
это работает отлично. Я хочу сделать с помощью IplImage. Пожалуйста помоги
saturate_cast для C ++.
http://docs.opencv.org/modules/core/doc/intro.html
Наконец-то я решил эту проблему.
IplImage* img;
cvNamedWindow("Display");
while(true)
{
img = cvLoadImage("Moori.jpg");
CvScalar brVal = cvScalarAll(abs(10.0));
cvAddS(img, brVal, img, NULL);
IplImage *pTempImg = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, img->nChannels);
cvSet( pTempImg, cvScalarAll(1), NULL );
double scale = 1.5;
cvMul(img, pTempImg, img, scale);
cvReleaseImage(&pTempImg);
cvShowImage("Display", img);
cvReleaseImage(&img);
int c=cvWaitKey(10);
if(c==27) break;
}
cvDestroyWindow("Display");
Вам не нужно бросать значения изображения в uchar
, Ты должен переосмысливать значения как uchar
, Это означает, что вы должны предположить, что биты данных на самом деле представляют собой unsigned char
независимо от типа указателя. Это можно сделать следующим образом:
uchar* ptr = reinterpret_cast<uchar*>(imageGray->imageData);
ptr[i] = saturate_cast<uchar>(alpha * ptr[i] + beta);
Если вы используете C ++, я не уверен, почему кто-то захочет использовать IplImage. Но ваша проблема в этой линии
imageGray->imageData[i] = (alpha * input_img->imageData[i]) + beta;
Это может переполниться. Также imageData является символом *, и символ может быть подписан или не подписан, вам нужно сделать его без знака. Вам нужно использовать saturate_cast чтобы предотвратить переполнение, и приведение, чтобы избавиться от подписанного символа:
imageGray->imageData[i] = saturate_cast<uchar>((alpha * static_cast<uchar>(input_img->imageData[i])) + beta);
Вы можете использовать эту маленькую программу, чтобы увидеть, что происходит:
#include <opencv2/core/core.hpp>
#include <iostream> // std::cout
#include <vector> // std::vector
int main(int argc, char** argv)
{
double alpha = 1.6;
int beta = 50;
std::vector<uchar> z;
for(int i = 0; i <= 255; ++i)
z.push_back(i);
char* zp = reinterpret_cast<char *>(&z[0]);
for(int i = 0; i <= 255; ++i)
std::cout << i << " -> " << int(cv::saturate_cast<uchar>(alpha * static_cast<uchar>(zp[i]) + beta)) << std::endl;
}