概述
时间为友,记录点滴。
写点什么呢?这两天刚好把另一个专栏《数字图像处理》更新到了“数字图像处理中所用数学工具的介绍”,那不如这样吧,我们把这里面的例子,都用OpenCV来实现一下。
lowkeyway:第二章 数字图像基础-(六)数字图像处理中所用数学工具的介绍zhuanlan.zhihu.com先抄过来大纲:
- 图像的像素级运算
点运算—— 线性点运算、非线性点运算
代数运算—— 加法、减法、乘法、除法
逻辑运算—— 求反、异或、或、与
- 图像的空域变换
几何变换
非几何变换
恩,柿子挑软的捏,用我们已经讲过的知识加一点拓展来实现。
忽然发现如果我把所有的运算放到一片文章里,这篇文章就太长了,分开吧。本文先说线性点运算。
线性点操作
公式:
那么它是如何跟图像对应的呢?
- a=1, b=0: 恒等
- a<0: 黑白翻转
- |a|>1: 增加对比度
- |a|<1: 减小对比度
- b>0: 增加亮度
- b<0: 减小亮度
好要求就这么多。
首先,我们要选择一张适合的照片,我是在OpenCv的github中挑了一张,因为它有黑白方格,很容易看到现象。
图片来源:
opencv/opencvgithub.comC++版本:
注意点:
- 用saturate_cast修饰词来限制内存不越界。
- 用Vec3b来表示一个3个uchar组成的数组。
- 因为用的图是一个3通道的色彩图,所以取反的时候其实是用255减的。
- 如果做实验,只要修改linearTest函数的传参即可。
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
static void showImgPara(Mat &img);
static void linearTest(string name, float a, float b);
int main()
{
linearTest("left06.jpg", 0.5, 0);
waitKey(0);
return 0;
}
static void showImgPara(Mat &img)
{
cout << "sizeof(img) is: " << sizeof(img) << ", img size is: " << img.size << endl;
cout << "rows x cols: (" << img.rows << " x " << img.cols << ")" << endl;
cout << "dims: " << img.dims << endl;
cout << "channels: " << img.channels() << endl;
cout << "type: " << img.type() << endl;
cout << "depth:" << img.depth() << endl;
cout << "elemSize:" << img.elemSize() << " (Bytes per element)" << endl;
cout << "elemSize1:" << img.elemSize1() << "(Bytes per channel)" << endl;
cout << "step[0]: " << img.step[0] << " (Bytes per cows only when 2 dims)" << endl;
cout << "step[1]: " << img.step[1] << " (Bytes per element only when 2 dims)" << endl;
cout << "step1(0): " << img.step1(0) << ", step1(1): " << img.step1(1) << " (step / elemSize1)" << endl;
}
static void linearTest(string name, float a, float b)
{
/* Original Picture */
Mat imgOri = imread(name);
showImgPara(imgOri);
namedWindow("original");
imshow("original", imgOri);
/* Output Picture */
Mat imgOut = Mat::ones(imgOri.size(), imgOri.type());
//namedWindow("zeros");
//imshow("zeros", imgOut);
uchar bOri = 0, gOri = 0, rOri = 0;
for (int i = 0; i < imgOri.cols; i++)
{
for (int j = 0; j < imgOri.rows; j++)
{
bOri = imgOri.at<Vec3b>(j, i)[0];
gOri = imgOri.at<Vec3b>(j, i)[1];
rOri = imgOri.at<Vec3b>(j, i)[2];
if (a >= 0)
{
imgOut.at<Vec3b>(j, i)[0] = saturate_cast<uchar>(a*bOri + b);
imgOut.at<Vec3b>(j, i)[1] = saturate_cast<uchar>(a*gOri + b);
imgOut.at<Vec3b>(j, i)[2] = saturate_cast<uchar>(a*rOri + b);
}
else
{
imgOut.at<Vec3b>(j, i)[0] = saturate_cast<uchar>(255 + a*bOri + b);
imgOut.at<Vec3b>(j, i)[1] = saturate_cast<uchar>(255 + a*gOri + b);
imgOut.at<Vec3b>(j, i)[2] = saturate_cast<uchar>(255 + a*rOri + b);
}
}
}
namedWindow("output");
imshow("output", imgOut);
}
来看看结果吧
a=1, b=0: 恒等
a<0: 黑白翻转
注意黑白方格,是刚好翻转的。
|a|>1: 增加对比度
|a|<1: 减小对比度
b>0: 增加亮度
b<0: 减小亮度
Python:
使用python就容易多了,感叹一下numpy的广播机制666
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:lowkeyway time:7/16/2019
import sys
import numpy as np
import cv2 as cv
def showImgPara(img):
print("Sizeof img is: " + str(img.size))
print("rows x cols is: " + str(np.size(img, 0)) + " x " + str(np.size(img, 1)))
print("dimension is: ", img.ndim)
print("dtype is: ", img.dtype)
print("itemsize is: ", img.itemsize)
print("shape is(rows, cols, depth): ", img.shape)
def linear(picName, a, b):
##################### Original Picture #####################
imgOri = cv.imread(picName)
cv.namedWindow("imgOri")
cv.imshow("imgOri", imgOri)
showImgPara(imgOri)
##################### Output Picture #####################
imgOut = np.zeros(imgOri.shape, imgOri.dtype)
if(a >= 0):
imgOut = a * imgOri + b
else:
imgOut = 255 - (-a)*imgOri + b
cv.namedWindow("imgOut")
cv.imshow("imgOut", imgOut)
def main_func(argv):
linear("left06.jpg", -1, 0)
cv.waitKey(0)
if __name__ == '__main__':
main_func(sys.argv)
结果输出跟C++一致,不贴了。
最后
以上就是无奈银耳汤为你收集整理的opencv mat 修改_(九)OpenCV中的数学运算(线性点运算)的全部内容,希望文章能够帮你解决opencv mat 修改_(九)OpenCV中的数学运算(线性点运算)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复