图像旋转,伪造图像直方图

时间:2019-07-18 07:21:00

标签: c++ image qt opencv image-processing

我得到了那个函数,通过给它一个整数值,它将旋转我的图像(我正在使用OpenCV存储该对象)。

这是我的旋转功能代码:

float rads = angle*3.1415926/180.0;
float _cos = cos(-rads);
float _sin = sin(-rads);
float xcenter = (float)(src.cols)/2.0;
float ycenter = (float)(src.rows)/2.0;

for(int i = 0; i < src.rows; i++) {
    for(int j = 0; j < src.cols; j++) {
        int x = ycenter + ((float)(i)-ycenter)*_cos - ((float)(j)-xcenter)*_sin;
        int y = xcenter + ((float)(i)-ycenter)*_sin + ((float)(j)-xcenter)*_cos;
        if (x >= 0 && x < src.rows && y >= 0 && y < src.cols) {
            dst.at<cv::Vec3b>(i ,j) = src.at<cv::Vec3b>(x, y);
        } else
            dst.at<cv::Vec3b>(i ,j) = NULL;
    }
}

如您所见,最后一行将NULL值设置为“空”像素,即为结果:

enter image description here

如您所见,由于现在我有很多黑色像素,因此右上角的直方图不再可靠,因为旋转图像时,直方图应保持为:

enter image description here

这是我计算3个直方图的代码:

int k = 0, r = 255, g = 255, b = 255;
switch (channel){ 
    case 0:
        k = 0; r = 255; g = 0; b = 0;
        break;
    case 1:
        k = 1; r = 0; g = 255; b = 0;
        break;
    case 2:
        k = 2; r = 0; g = 0; b = 255;
        break;
}

int hist[256];
for(int i = 0; i < 255; i++)
    hist[i] = 0;

for(int i = 0; i < img.rows; i++)
    for(int j = 0; j < img.cols; j++)
        hist[(int)img.at<cv::Vec3b>(i,j)[k]]++;

int hist_w = 299;
int hist_h = 69;
int bin_w = cvRound((double) hist_w/256);

cv::Mat histImage(hist_h, hist_w, CV_8UC3, cv::Scalar(50, 50, 50));

int max = hist[0];

for(int i = 1; i < 256; i++)
    if(max < hist[i])
        max = hist[i];

for(int i = 0; i < 255; i++)
        hist[i] = ((double)hist[i]/max)*histImage.rows;

for(int i = 0; i < 255; i++)
    line(histImage, cv::Point(bin_w*(i), hist_h), cv::Point(bin_w*(i), hist_h - hist[i]), cv::Scalar(r,g,b), 1, 8, 0);

return histImage;

有人知道我该如何解决吗?

1 个答案:

答案 0 :(得分:3)

您有意识地向图像添加黑色像素并抱怨这会改变直方图,这有点奇怪!请注意,新的直方图就是…正确。

这就是说,您将通过清除三个通道中的0 bins,来获得图像非黑色部分的直方图。

如果出于某种原因要避免那些黑色区域而又不会过多地干扰初始直方图,则可以选择用从初始图像中随机采样的像素填充它们。图片会很丑陋,但直方图很安全。