可以给我一段完整的代码,利用VS+ Opencv 实现打开一张图片并进行双三次插值
时间: 2023-06-01 20:07:31 浏览: 91
当然可以,以下是完整的代码:
```
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("image.jpg"); // 读取图片
if (img.empty()) // 如果图片加载失败,输出错误信息
{
cout << "无法加载图片!" << endl;
return -1;
}
namedWindow("原图", WINDOW_NORMAL); // 创建一个名为“原图”的窗口
imshow("原图", img); // 在窗口中显示原图
Mat dst;
resize(img, dst, Size(0, 0), 2, 2, CV_INTER_CUBIC); // 双三次插值
namedWindow("插值后", WINDOW_NORMAL); // 创建一个名为“插值后”的窗口
imshow("插值后", dst); // 在窗口中显示插值后的图片
waitKey(0); // 等待用户按下任意键
return 0;
}
```
这段代码利用 OpenCV 库中的 `imread` 函数读取一张图片,然后通过 `resize` 函数对图片进行双三次插值,最后在窗口中显示出原图和插值后的图片。
相关问题
可以帮我写一段代码,利用VS+opencv+QT 实现打开一张图片并实现双线性插值,双三次插值
当然可以,以下是实现代码:
```cpp
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 打开图片
Mat srcImg = imread("lena.jpg");
if (srcImg.empty()) {
cout << "无法打开图片!" << endl;
return -1;
}
// 缩小一半
Mat dstImg1, dstImg2;
resize(srcImg, dstImg1, Size(), 0.5, 0.5, INTER_LINEAR);
// 双线性插值
resize(srcImg, dstImg2, Size(), 0.5, 0.5, INTER_CUBIC);
// 显示结果
namedWindow("SRCImage", WINDOW_AUTOSIZE);
namedWindow("LinearInterpolation", WINDOW_AUTOSIZE);
namedWindow("CubicInterpolation", WINDOW_AUTOSIZE);
imshow("SRCImage", srcImg);
imshow("LinearInterpolation", dstImg1);
imshow("CubicInterpolation", dstImg2);
waitKey(0);
return 0;
}
```
这段代码可以实现利用OpenCV读取一张图片并进行双线性插值和双三次插值。
给我一段完整的代码,利用VS+opencv+QT实现做一个用户交互界面,使得可以实现打开图片,保存图片,可以实现双线性插值,双三次插值,可以实现直方图均衡,可以进行拉普拉斯,sobel梯度处理
抱歉,由于篇幅限制,无法提供完整的代码。但是,我可以给您提供一些实现这些功能的代码片段,并指导您如何利用VS+opencv+QT实现用户交互界面。
首先,您需要安装OpenCV和QT,并将它们配置到您的VS项目中。然后,您可以开始编写代码了。
打开图片和保存图片:
```c++
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat image = imread("input.jpg");
if (image.empty())
{
cout << "Could not open or find the image" << endl;
return -1;
}
// 显示图像
namedWindow("Original Image", WINDOW_NORMAL);
imshow("Original Image", image);
// 保存图像
imwrite("output.jpg", image);
waitKey(0);
destroyAllWindows();
return 0;
}
```
双线性插值和双三次插值:
```c++
// 双线性插值
Mat bilinearInterpolation(Mat& image, double sx, double sy)
{
int w = image.cols;
int h = image.rows;
int dst_w = int(w * sx + 0.5);
int dst_h = int(h * sy + 0.5);
Mat dst(dst_h, dst_w, CV_8UC3, Scalar(0, 0, 0));
for (int i = 0; i < dst_h; i++)
{
for (int j = 0; j < dst_w; j++)
{
int x = int(j / sx);
int y = int(i / sy);
double u = j / sx - x;
double v = i / sy - y;
if (x >= w - 1 || y >= h - 1)
{
continue;
}
for (int k = 0; k < 3; k++)
{
dst.at<Vec3b>(i, j)[k] = (1 - u) * (1 - v) * image.at<Vec3b>(y, x)[k] +
u * (1 - v) * image.at<Vec3b>(y, x + 1)[k] +
(1 - u) * v * image.at<Vec3b>(y + 1, x)[k] +
u * v * image.at<Vec3b>(y + 1, x + 1)[k];
}
}
}
return dst;
}
// 双三次插值
Mat bicubicInterpolation(Mat& image, double sx, double sy)
{
int w = image.cols;
int h = image.rows;
int dst_w = int(w * sx + 0.5);
int dst_h = int(h * sy + 0.5);
Mat dst(dst_h, dst_w, CV_8UC3, Scalar(0, 0, 0));
for (int i = 0; i < dst_h; i++)
{
for (int j = 0; j < dst_w; j++)
{
int x = int(j / sx);
int y = int(i / sy);
double u = j / sx - x;
double v = i / sy - y;
if (x >= w - 3 || y >= h - 3)
{
continue;
}
double A[4][4];
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < 4; l++)
{
double coeff = 1;
for (int m = 0; m < 4; m++)
{
if (m != k)
{
coeff *= (u - m) / (k - m);
}
}
for (int m = 0; m < 4; m++)
{
if (m != l)
{
coeff *= (v - m) / (l - m);
}
}
A[k][l] = coeff;
}
}
for (int k = 0; k < 3; k++)
{
double sum = 0;
for (int l = 0; l < 4; l++)
{
for (int m = 0; m < 4; m++)
{
sum += A[l][m] * image.at<Vec3b>(y + l, x + m)[k];
}
}
dst.at<Vec3b>(i, j)[k] = int(sum + 0.5);
}
}
}
return dst;
}
```
直方图均衡:
```c++
Mat histogramEqualization(Mat& image)
{
Mat dst;
cvtColor(image, dst, COLOR_BGR2YCrCb);
vector<Mat> channels;
split(dst, channels);
equalizeHist(channels[0], channels[0]);
merge(channels, dst);
cvtColor(dst, dst, COLOR_YCrCb2BGR);
return dst;
}
```
拉普拉斯和Sobel梯度处理:
```c++
Mat laplacianFilter(Mat& image)
{
Mat src_gray, dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);
cvtColor(image, src_gray, COLOR_BGR2GRAY);
Mat abs_dst;
Laplacian(src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
return abs_dst;
}
Mat sobelFilter(Mat& image)
{
Mat src_gray, dst;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
GaussianBlur(image, image, Size(3, 3), 0, 0, BORDER_DEFAULT);
cvtColor(image, src_gray, COLOR_BGR2GRAY);
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
Sobel(src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
Sobel(src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
return dst;
}
```
在QT中实现用户交互界面:
您需要创建一个QT窗口,并添加一些按钮和标签来实现用户交互。您可以使用QFileDialog来打开和保存图像,使用QComboBox来选择插值方法和处理方法,使用QLabel来显示原始图像和处理后的图像。您可以在按钮的clicked信号中调用相应的函数,并在标签中显示图像。
```c++
void MainWindow::on_openBtn_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));
if (fileName.isEmpty())
{
return;
}
Mat image = imread(fileName.toStdString());
if (image.empty())
{
QMessageBox::warning(this, tr("Error"), tr("Could not open or find the image!"));
return;
}
m_srcImage = image.clone();
m_dstImage = image.clone();
// 显示原始图像
QImage qImage = Mat2QImage(m_srcImage);
ui->srcLabel->setPixmap(QPixmap::fromImage(qImage));
ui->srcLabel->setFixedSize(qImage.size());
}
void MainWindow::on_saveBtn_clicked()
{
if (m_dstImage.empty())
{
QMessageBox::warning(this, tr("Error"), tr("The image is empty!"));
return;
}
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save Image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));
if (fileName.isEmpty())
{
return;
}
imwrite(fileName.toStdString(), m_dstImage);
}
void MainWindow::on_interpolationComboBox_currentIndexChanged(int index)
{
double sx = ui->scaleXLineEdit->text().toDouble();
double sy = ui->scaleYLineEdit->text().toDouble();
switch (index)
{
case 0: // 双线性插值
m_dstImage = bilinearInterpolation(m_srcImage, sx, sy);
break;
case 1: // 双三次插值
m_dstImage = bicubicInterpolation(m_srcImage, sx, sy);
break;
default:
break;
}
// 显示处理后的图像
QImage qImage = Mat2QImage(m_dstImage);
ui->dstLabel->setPixmap(QPixmap::fromImage(qImage));
ui->dstLabel->setFixedSize(qImage.size());
}
void MainWindow::on_processComboBox_currentIndexChanged(int index)
{
switch (index)
{
case 0: // 直方图均衡
m_dstImage = histogramEqualization(m_srcImage);
break;
case 1: // 拉普拉斯
m_dstImage = laplacianFilter(m_srcImage);
break;
case 2: // Sobel梯度
m_dstImage = sobelFilter(m_srcImage);
break;
default:
break;
}
// 显示处理后的图像
QImage qImage = Mat2QImage(m_dstImage);
ui->dstLabel->setPixmap(QPixmap::fromImage(qImage));
ui->dstLabel->setFixedSize(qImage.size());
}
```
最后,您需要实现一个将OpenCV的Mat类型图像转换为QT的QImage类型的函数。
```c++
QImage Mat2QImage(const Mat& image)
{
if (image.empty())
{
return QImage();
}
Mat dst;
if (image.channels() == 1)
{
dst = Mat(image.rows, image.cols, CV_8UC1, Scalar(0));
cvtColor(image, dst, COLOR_GRAY2RGB);
}
else if (image.channels() == 3)
{
dst = image.clone();
cvtColor(image, dst, COLOR_BGR2RGB);
}
else
{
return QImage();
}
QImage qImage(dst.data, dst.cols, dst.rows, dst.step, QImage::Format_RGB888);
return qImage;
}
```
阅读全文