c++ - 图像旋转,伪造图像直方图

标签 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;

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

最佳答案

你有意识地在图像中添加黑色像素并提示这修改了直方图,这有点奇怪!请注意,新的直方图非常……正确。

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

如果出于某种原因你想避免那些黑色区域而不会对初始直方图造成太多干扰,并且可以选择用从初始图像随机采样的像素填充它们。图像会很难看,但直方图是安全的。

关于c++ - 图像旋转,伪造图像直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57089107/

相关文章:

c++ - Visual Studio 线程 - afxwin 还是 C++11 线程?

c++ - 如何在没有持久索引损坏/重复的情况下使用 beginMoveRows 进行排序?

java - Android Studio : Layout hierarchy problems

javascript - 将图像放入 chrome.storage 扩展中

javascript - 最佳文件上传方式

c++ - memset() 在 C++ 中的工作原理

c++ - 如何修复 "non-aggregates cannot be initialized with initializer list” < map >

c++ - QPainter 中的文本比 QPainterPath 中的文本好得多

c++ - 在进入事件时填充 QRect

c++ - Qt/从主窗口发送数据到对话框或从主窗口抓取数据?