参考贾志刚的opencv图像处理方法,对一张倾斜图片进行矫正。条条大路通罗马,对一张倾斜图片进,有很多方法,这是最复杂的一种,通过求四个倾斜角点的位置,再设置目标点的位置,通过仿射变换进行图片矫正。
与PS方法的优势就是可以通过代码批量处理图片。
图片:
只能说这种方法确实比较好,特别是在进行图片批处理的时候,虽然复杂了点,但是能保证对大部分图片效果较好。
主要流程:
1 . 二值化
形态学操作,去噪点
进行轮廓查找, 通过 矩形的长款过滤较小和图片的大边框
霍夫直线变换,查找直线
过滤直线,通过直线位置和长度确定上下左右四条直线
求出四条直线
得到四条直线的交点,这就是物体原始四个角点
把原始的四个角点,变换到图片的四个角落,透视变换会把相对位置的像素通过线性插值填充
#include
#include
#include
using namespace cv;
using namespace std;
Mat src, dst, gray_src;
char input_image[] = "input image";
char output_image[] = "output image";
int main(int argc, char ** argv){
src = imread("case5.jpg");
if (src.empty()){
printf("colud not load image ..\n");
return -1;
}
namedWindow(input_image, CV_WINDOW_AUTOSIZE);
namedWindow(output_image, CV_WINDOW_AUTOSIZE);
imshow(input_image, src);
// 二值化处理
Mat binary;
cvtColor(src, gray_src, COLOR_BGR2GRAY);
threshold(gray_src, binary, 0, 255, CV_THRESH_BINARY_INV | THRESH_OTSU);
imshow("binary image", binary);
// 腐蚀操作
Mat structureElement = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
dilate(binary, binary, structureElement); //腐蚀
imshow("erode", binary);
// 形态学操作
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary, dst, MORPH_OPEN, kernel, Point(-1, -1), 3);
imshow("morphology", dst);
// 轮廓发现
bitwise_not(dst, dst, Mat());
vector> contours;
vector hireachy;
int width = src.cols;
int height = src.rows;
Mat drawImage = Mat::zeros(src.size(), CV_8UC3);
findContours(dst, contours, hireachy, CV_RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
for (size_t t = 0; t < contours.size(); t++){
Rect rect = boundingRect(contours[t]);
printf("rect.width : %d, src.cols %d \n ", rect.width, sr