#include
#include
#include
using namespace cv;
int main(int argc, char* argv) {
Mat src = imread(".\\res\\1.png");
Rect rect(0, 0, 200, 200);
Mat roi = src(rect);
MatSize roiSize = roi.size;
namedWindow("src");
namedWindow("roi", WINDOW_AUTOSIZE);
imshow("src", src);
imshow("roi", roi);
waitKey(0);
return 0;
}
像素格式和灰度图
RGB:红绿蓝
YUV:亮度、色度、饱和度
GRAY:0-255表示亮度,颜色没有意义时用灰度图,比如OCR
转换公式:GRay = (R30 + G59 + B*11 +50)/100
#include
#include
#include
#include
using namespace cv;
int PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0) {
last = cur;
}
long long ms = ((double)(cur - last) / getTickFrequency()) * 1000;
if (*text != 0) {
printf("%s = %d ms\n", text, ms);
}
last = getTickCount();
return 0;
}
void RGBToGray(Mat src, Mat &des)
{
des.create(src.rows, src.cols, CV_8UC1);
for (int r = 0; r < src.rows; r++)
{
for (int c = 0; c < src.cols; c++)
{
Vec3b &m = src.at<Vec3b>(r, c);
// GRay = (R*30 + G*59 + B*11 +50)/100
int gray = (m[2] * 30 + m[1] * 59 + m[0] * 11 + 50) / 100;
des.at<uchar>(r, c) = gray;
}
}
}
int main(int argc, char* argv) {
Mat src = imread(".\\res\\1.png");
Mat gray;
Mat mygray;
PrintMs("");
cvtColor(src, gray, COLOR_BGR2GRAY);
PrintMs("gray ms");
RGBToGray(src, mygray);
PrintMs("mygray ms");
namedWindow("gray");
imshow("gray", gray);
namedWindow("mygray");
imshow("mygray", mygray);
namedWindow("src");
imshow("src", src);
waitKey(0);
return 0;
}
opencv-阈值处理
threshold(gray, bin, 100, 255, THRESH_BINARY);
threshold(gray, ibin, 100, 255, THRESH_BINARY_INV);
int main(int argc, char* argv) {
Mat src = imread(".\\res\\1.png");
Mat bin;
Mat ibin;
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
//二进制阈值化
threshold(gray, bin, 100, 255, THRESH_BINARY);
//反二进制阈值化
threshold(gray, ibin, 100, 255, THRESH_BINARY_INV);
namedWindow("src");
namedWindow("bin");
namedWindow("ibin");
imshow("src", src);
imshow("bin", bin);
imshow("ibin", ibin);
waitKey(0);
return 0;
}
saturate_cast<uchar>();
在图像处理方面,无论是加是减,乘除,都会超出一个像素灰度值的范围(0~255),saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。
#include
#include
#include
#include
using namespace cv;
int PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0) {
last = cur;
}
long long ms = ((double)(cur - last) / getTickFrequency()) * 1000;
if (*text != 0) {
printf("%s = %d ms\n", text, ms);
}
last = getTickCount();
return 0;
}
//
///@para a float 对比度 1.0~3.0
///@para b int 亮度 0~100
void ChangeGain(Mat &src, Mat &des, float a, int b)
{
//g(r,c) = a*f(r,c) + b
des.create(src.rows, src.cols, src.type());
for (int r = 0; r < src.rows; r++)
{
for (int c = 0; c < src.cols; c++)
{
for (int i = 0; i < 3; i++)
{
des.at<Vec3b>(r, c)[i] = saturate_cast<uchar>(a * src.at<Vec3b>(r, c)[i] + b);
}
}
}
}
int main(int argc, char *argv[])
{
//调整对比度和亮度
Mat src = imread(".\\res\\1.png");
Mat des;
PrintMs("");
ChangeGain(src, des, 2.0, 50);
PrintMs("ChangeGain");
Mat des2;
src.convertTo(des2, -1, 2.0, 50);
PrintMs("convertTo");
namedWindow("src");
namedWindow("des");
namedWindow("des2");
imshow("src", src);
imshow("des", des);
imshow("des2", des2);
waitKey(0);
return 0;
}
是对图像进行缩放的一种方式
性能好 效果差
性能稍差,但效果好
void xresize(Mat &src, Mat &des, Size size)
{
des.create(size, src.type());
//映射的原图坐标
int sx, sy = 0;
float fx = (float)src.cols / des.cols;
float fy = (float)src.rows / des.rows;
for (int x = 0; x < des.cols; x++)
{
sx = fx * x + 0.5;
for (int y = 0; y <des.rows; y++)
{
sy = fy * y + 0.5;
des.at<Vec3b>(y, x) = src.at<Vec3b>(sy, sx);
}
}
}
int main(int argc, char *argv[])
{
Mat src = imread("1.png"); //512*512 256 1024
Mat img256,img1024,des256,des1024;
resize(src, des256, Size(256, 256), 0, 0, INTER_NEAREST);
PrintMs();
//xresize(src, img256, Size(256, 256));
//PrintMs("img256");
xresize(src, img1024, Size(1024, 1024));
//resize(src, img1024, Size(4024, 4024), 0, 0, INTER_NEAREST);
PrintMs("img1024");
//resize(src, des256, Size(1024, 1024), 0, 0, INTER_NEAREST);
resize(src, des1024, Size(1024, 1024), 0, 0, INTER_LINEAR);
PrintMs("des1024");
namedWindow("src");
//namedWindow("img256");
namedWindow("des1024");
namedWindow("img1024");
imshow("src", src);
imshow("img1024", img1024);
imshow("des1024", des1024);
//imshow("img1024", img1024);
waitKey(0);
return 0;
}
输入图像中像素的小邻域来产生输出图像的方法,在信号处理中这种方法称为滤波( filtering)。其中,最常用的是线性滤波,输出像素是输入邻域像素的加权和。
三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法
也是对图像进行缩放的一种方式
用来向下采样缩小
用来从金字塔低层图像重建上层未采样图像 放大
int main(int argc, char *argv[])
{
Mat src = imread(".\\res\\1.png"); //512*512 256 1024
Mat gsrc;
Mat lsrc;
pyrDown(src, gsrc);
pyrUp(src, lsrc);
namedWindow("src");
moveWindow("src", 0, 0);
namedWindow("gsrc");
moveWindow("gsrc", 512, 0);
namedWindow("lsrc");
moveWindow("lsrc", 0, 512);
imshow("src", src);
imshow("gsrc", gsrc);
imshow("lsrc", lsrc);
cvWaitKey(0);
return 0;
}
cv:: rotate(src, dst, type);
-ROTATE_180
-ROTATE_90_CLOCKWISE
-ROTATE 90 COUNTERCLOCKWISE
cv:flip(src, dst, type); //type 0(x),1(y),-1
int main(int argc, char *argv[])
{
Mat img = imread(".\\res\\1.png");
Mat rot;
Mat fl;
cv::rotate(img, rot, ROTATE_90_CLOCKWISE);
cv::flip(img, fl,1); //type 0(x), 1(y), -1
namedWindow("src");
namedWindow("rot");
namedWindow("fl");
imshow("src", img);
imshow("rot", rot);
imshow("fl", fl);
waitKey(0);
return 0;
}
int main(int argc, char *argv[])
{
Mat img1 = imread(".\\res\\1.png");
Mat img2 = imread(".\\res\\2.jpg");
int height = img1.rows;
int width1 = img1.cols;
int width2 = img2.cols;
// 将高图像等比缩放与低图像高度一致
if (img1.rows > img2.rows)
{
height = img2.rows;
width1 = img1.cols * ((float)img2.rows / (float)img1.rows);
resize(img1, img1, Size(width1, height));
}
else if (img1.rows < img2.rows)
{
width2 = img2.cols * ((float)img1.rows / (float)img2.rows);
resize(img2, img2, Size(width2, height));
}
//创建目标Mat
Mat des;
des.create(height, width1 + width2, img1.type());
Mat r1 = des(Rect(0, 0, width1, height));
img1.copyTo(r1);
Mat r2 = des(Rect(width1, 0, width2, height));
img2.copyTo(r2);
namedWindow("des");
imshow("des", des);
waitKey(0);
return 0;
}