实验3目录
实验内容
- 读入一副图像,转换为灰度图像,分别使用对数、指数、线性拉伸的灰度变换方法对图像进行变换,比较变换前后的图像;
运行效果
原图:
灰度读入:
灰度化图像的指数变换:
原图的指数变换:
对数图像:
线性拉伸:
项目源码
项目组织格式:
Sources
DigitalGraphicExp3.cpp
// DigitalGraphicExp3.cpp
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include "expTransform.h"
#include "logTransform.h"
#include "linearTransform.h"
using namespace cv;
int main()
{
String img_name = "../media/cat.jpg";
// Log
logTransform(img_name);
// Exp
expTransform(img_name);
// Linear
linearTransform(img_name);
return 0;
}
expTransform.cpp
// expTransform.cpp
#include "expTransform.h"
static void init_lookup_table(uchar* lookup_table) {
double c = 0.8;
int r = 2;
for (int i = 0; i < 256; ++i) {
lookup_table[i] = int((c * pow(i / 255.0, r)) * 255 + 0.5);
}
}
void applyExp(Mat& I, const uchar* const table) {
uchar *p_row = NULL; // Start position of the row
int nRow = I.rows;
int nCol = I.cols * I.channels();
if (I.isContinuous()) {
nCol *= nRow;
nRow = 1;
}
for (int i = 0; i < nRow; ++i) {
p_row = I.ptr<uchar>(i);
for (int j = 0; j < nCol; ++j) {
p_row[j] = table[p_row[j]];
}
}
}
void expTransform(String img_dir) {
uchar lookup_table[256];
String dir1 = "../media/cat.jpg";
init_lookup_table(lookup_table);
if (!img_dir.empty()) {
dir1 = img_dir;
}
Mat src = imread(dir1, IMREAD_GRAYSCALE);
if (src.empty()) {
std::cout << "Open Error" << std::endl;
std::cout << "dir1 = " << dir1 << std::endl;
waitKey(0);
return;
}
Mat dst = src.clone();
applyExp(dst, lookup_table);
imshow("ORIGIN IMG", src);
imshow("Exp IMG", dst);
waitKey(0);
}
linearTransform.cpp
// linearTransform.cpp
#include "linearTransform.h"
void linearTransform(String img_dir) {
String dir1 = "../media/cat.jpg";
if (!img_dir.empty()) {
dir1 = img_dir;
}
Mat src = imread(dir1, IMREAD_GRAYSCALE);
if (src.empty()) {
std::cout << "Open Error" << std::endl;
#ifdef Debug
std::cout << "dir1 = " << dir1 << std::endl;
waitKey(0);
#endif
return;
}
Mat dst = src.clone();
int nRows = dst.rows;
int nCols = dst.cols;
if (dst.isContinuous())
{
nCols = nCols * nRows;
nRows = 1;
}
uchar *pDataMat;
int pixMax = 0, pixMin = 255;
for (int j = 0; j < nRows; j++)
{
pDataMat = dst.ptr<uchar>(j);
for (int i = 0; i < nCols; i++)
{
if (pDataMat[i] > pixMax)
pixMax = pDataMat[i];
if (pDataMat[i] < pixMin)
pixMin = pDataMat[i];
}
}
// Linear stretch
for (int j = 0; j < nRows; j++)
{
pDataMat = dst.ptr<uchar>(j);
for (int i = 0; i < nCols; i++)
{
pDataMat[i] = (pDataMat[i] - pixMin) *
255 / (pixMax - pixMin);
}
}
imshow("Linear Streach", dst);
waitKey(0);
}
logTransform.cpp
// logTransform.cpp
#include "expTransform.h"
#include <cmath>
void logTransform(String img_dir) {
String dir1 = "../media/cat.jpg";
if (img_dir.empty()) {
dir1 = img_dir;
}
Mat srcImage = imread(dir1, IMREAD_GRAYSCALE);
int c = 2;
if (srcImage.empty()) {
std :: cout << "Open Error" << std :: endl;
}
Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());
add(srcImage, Scalar(1.0), srcImage);
srcImage.convertTo(srcImage, CV_32F);
log(srcImage, resultImage);
resultImage = c * resultImage;
// normalize
normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);
convertScaleAbs(resultImage, resultImage);
imshow("LOG IMG", resultImage);
}
Headers
expTransform.h
// expTransform.h
#pragma once
#include <opencv.hpp>
using namespace cv;
void applyExp(Mat& I, const uchar* const table);
void expTransform(String dir="");
linearTransform.h
// linearTransform.h
#pragma once
#include <opencv.hpp>
using namespace cv;
void linearTransform(String dir = "");
logTransform.h
// logTransform.h
#pragma once
#include <opencv.hpp>
using namespace cv;
void logTransform(String dir = "");