#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat image = imread("C:/Users/l/Desktop/1.bmp");
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
int blockSize = 8;
vector<cv::Mat> blocks;
for (int i = 0; i < grayImage.rows; i += blockSize) {
for (int j = 0; j < grayImage.cols; j += blockSize) {
Rect blockRect(j, i, blockSize, blockSize);
blocks.push_back(grayImage(blockRect));
}
}
vector<Mat> dctBlocks;
for (auto& block : blocks) {
Mat dctBlock;
dct(block, dctBlock);
dctBlocks.push_back(dctBlock);
}
int nCoefficients = 10;
for (auto& dctBlock : dctBlocks) {
for (int i = 0; i < dctBlock.rows; i++) {
for (int j = 0; j < dctBlock.cols; j++) {
if (i + j >= nCoefficients) {
dctBlock.at<float>(i, j) = 0;
}
}
}
}
Mat compressedImage(grayImage.size(), grayImage.type());
int blockIndex = 0;
for (int i = 0; i < compressedImage.rows; i += blockSize) {
for (int j = 0; j < compressedImage.cols; j += blockSize) {
Rect blockRect(j, i, blockSize, blockSize);
idct(dctBlocks[blockIndex], compressedImage(blockRect));
blockIndex++;
}
}
imshow("Original Image", grayImage);
imshow("Compressed Image", compressedImage);
waitKey(0);
return 0;
}
访问越界了,假设图像grayImage是10x20,17行Rect(8,8,8,8)不就越界了吗。姐妹加个不要超出图像的限制再去访问。同理44行。
在您的代码中,您将DCT变换后的块存储在名为“dctBlocks”的向量中。这些块的数据类型应该是 CV_32F
,因为DCT变换返回的是浮点数,而不是整数。然而,由于您将DCT块在向量中存储为 cv::Mat
类型而没有指定数据类型,因此默认情况下使用了 CV_8U
。
修改您的代码,将DCT块在向量中存储为 CV_32F
类型:
for (auto& block : blocks) {
Mat dctBlock;
dct(block, dctBlock);
dctBlock.convertTo(dctBlock, CV_32F); // 将数据类型转换为 CV_32F
dctBlocks.push_back(dctBlock);
}
另外,在您在阈值之后将某些DCT系数设置为零时,因为抛出的异常是溢出,可能是由于某些块的所有系数都被截断为零,导致在 IDCT 时出现除以零的情况。检查您的代码,确保在将某些系数设置为零后不会出现这种情况。
不知道你这个问题是否已经解决, 如果还没有解决的话:虽然这个库使用起来十分的方便,但他还是有它的缺点在里面,最大的缺陷就在于它只能较为精准的识别出英文,而没有办法对类似中文的文字进行提取。
很抱歉,由于缺乏具体错误信息以及您的代码,我无法为您优化代码或提供详细解决方案。建议您确定错误信息,并提供具体的代码以供分析和更好的理解。感谢您的理解。