2017-04-10 45 views
0

首先我想强调我是新手opencv。自动裁剪特定部分的图像

我有一个电表的这个形象像这样:

而且我想处理图像,只是得到这样的:

从什么我讲师告诉我们,我们首先需要找到轮廓,然后通过获取图像的矩形部分来处理图像。

不知道这是否是相关的,我使用的OpenCV 2.4.13

这是一个基于教程寻找轮廓

#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 

using namespace cv; 
using namespace std; 

Mat src; Mat src_gray; 
int thresh = 100; 
int max_thresh = 255; 
RNG rng(12345); 

/// Function header 
void thresh_callback(int, void*); 

/** @function main */ 
int main(int argc, char** argv) 
{ 
    /// Load source image and convert it to gray 
    src = imread(argv[1], 1); 

    /// Convert image to gray and blur it 
    cvtColor(src, src_gray, CV_BGR2GRAY); 
    blur(src_gray, src_gray, Size(3,3)); 

    /// Create Window 
    char* source_window = "Source"; 
    namedWindow(source_window, CV_WINDOW_AUTOSIZE); 
    imshow(source_window, src); 

    createTrackbar(" Canny thresh:", "Source", &thresh, max_thresh, thresh_callback); 
    thresh_callback(0, 0); 

    waitKey(0); 
    return(0); 
} 

/** @function thresh_callback */ 
void thresh_callback(int, void*) 
{ 
    Mat canny_output; 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 

    /// Detect edges using canny 
    Canny(src_gray, canny_output, thresh, thresh*2, 3); 
    /// Find contours 
    findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

    /// Draw contours 
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3); 
    for(int i = 0; i< contours.size(); i++) 
    { 
     Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255)); 
     drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point()); 
    } 

    /// Show in a window 
    namedWindow("Contours", CV_WINDOW_AUTOSIZE); 
    imshow("Contours", drawing); 
} 
+0

投票关闭,因为它不清楚问题是关于裁剪图像还是加载图像。 – Mikhail

+0

在投票前你可能会问。图像将被加载,然后被自动裁剪。 如果mods发现它需要关闭它,那就这样吧。 – user3079169

回答

3

您应执行以下步骤的代码:

  1. 本地化恒温器上的液晶显示器 - 这可以通过边缘检测来完成,因为塑料壳和LCD之间有足够的对比度。

  2. 提取液晶显示器 - 给定输入边缘图,您可以找到轮廓并查找具有矩形形状的轮廓 - 最大的矩形区域应对应于LCD。 A perspective transform会给你一个很好的LCD提取。

:(在python) example.jpg

# load the example image 
image = cv2.imread("example.jpg) 

# pre-process the image by resizing it, converting it to gray scale,blurring it and computing an edge map 
image = imutils.resize(image, height = 500) 
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # OpenCV loads RGB as BGR 
blurred = cv2.GaussianBlur(gray, (5, 5), 0) # Essentially reduces high frequency noise try with/without for your case 
edged = cv2.Canny(blurred, 50, 200, 255); 

Edge map

# Extracting LCD here 
# find contours in the edge map, then sort them by their size in descending order 
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 
cnts = cnts[0] if imutils.is_cv2() else cnts[1] 
cnts = sorted(cnts, key=cv2.contourArea, reverse=True) # you can sort contours in C++ using implementation for std::vector 
displayCnt = None 

# loop over the contours 
for c in cnts: 
    # approximate the contour 
    peri = cv2.arcLength(c, True) 
    approx = cv2.approxPolyDP(c, 0.02 * peri, True) 

    # if the contour has four vertices, then we have found the thermostat display 
    if len(approx) == 4: 
     displayCnt = approx. 
     break 

# extract the thermostat display, apply a perspective transform to it 
warped = four_point_transform(gray, displayCnt.reshape(4, 2)) 
output = four_point_transform(image, displayCnt.reshape(4, 2)) 

Warped Image

功能four_point_transformhere

您可能需要对代码进行一些调整,具体取决于您的图像以及获取的内容。我会把它留给你。

+0

M这真的很特别+1 –

+1

@Jeru Luke Cheers mate :) –