您的位置:首页 > 运维架构 > Shell

使用OpenCV读、操作、写图像并与bash合作对某个目录下所有图像进行类似处理

2014-10-29 10:48 489 查看
我门要对某个目录下所有图像文件进行统一处理,如果图像的数量过多,那么手动地一张张处理就会显得有些麻烦。本文使用OpenCV和bash来完成我们指定的任务。

任务

将目录A下的所有统一格式的jpg图像变成统一尺寸的图像,输出到目录B中。A目录下图像的宽度和高度需要去掉最后一列、最后一行,并且使得输出图像的高度小于宽度。

技术

OpenCV读取图像;访问图像中的元素;OpenCV写图像到磁盘。

BASH扫描每个输入图像;确定输出图像名称。

OpenCV对图像进行处理

源代码如下:

#include <cassert>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include "cv.hpp"
#include "opencv2/opencv.hpp"
//#include "opencv2/core.hpp"
#include "opencv2/highgui/highgui_c.h"

using namespace std;
using namespace cv;

int main(int argc, char **argv)
{
if (3 != argc){
cerr << "input error\n";
cerr << "Usage : " << argv[0] << " <input image> <output directory>" << endl;
return -1;
}
// reading the input image
Mat oim = imread(argv[1]);
if (oim.empty())
return -1;

const int rows = oim.rows;
const int cols = oim.cols;
Mat fim(rows-1, cols-1, CV_8UC3);

for (int r = 0; r < (rows-1); r++){
for (int c = 0; c < (cols-1); c++){
fim.at<Vec3b>(r,c) = oim.at<Vec3b>(r,c);
}}
// rotate 90'
Mat lim;
if (rows > cols){
lim.create(cols-1, rows-1, CV_8UC3);
for (int r = 0; r < (cols-1); r++){
for (int c = 0; c < (rows-1); c++){
lim.at<Vec3b>(r,c) = fim.at<Vec3b>(c,cols-2-r);
}}
}
else{
lim = fim;
}
// saving
string filename(argv[1]);
int dirpos = filename.find_last_of('/');
if (string::npos == dirpos){
dirpos = 0;
}
else{
dirpos += 1;
}
string wfn = &filename[dirpos];
string outdir = string(argv[2]);
string outfile = outdir+string("/")+wfn;

vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
imwrite(outfile, lim, compression_params);
if(lim.cols != 480 || lim.rows != 320)
cerr << "size error" << endl;

return 0;
}


程序分三大步骤完成:读如程序选项中的输入图像;对输入图像去除最后一行和最后一列,判断高度和宽度的要求(是否进行反转90度);将图像写入磁盘。

写入磁盘时,使用了jpeg压缩方式,压缩的参数设置为100,表示无失真压缩。

输入图像的名称和输出图像的名称使用同一个。

bash处理

用bash对某个目录下的所有图像都处理一次,并且输出到指定的目录。源代码如下:

SPS="input/"

DFS=`ls -A ${SPS}*.jpg`

JPGDIR="../output/jpg"

mkdir -p ${JPGDIR}

for fn in $DFS
do
echo $fn
./rmRowACols.exe $fn $JPGDIR
done


总结

BASH+C/C++ 合作来完成一个完整的任务,各取所长,兼顾性能和开发难度,目前被我认为是比较简单的方式。

这样作还有一个好处:C\C++语言可以做更多细节,别调用别人的程序要随意一点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐