目标

在本教程中,您将学习如何:使用OpenCV功能matchTemplate()来搜索图像补丁和输入图像之间的匹配

使用OpenCV函数minMaxLoc()来查找给定数组中的最大值和最小值(以及它们的位置)。

理论

什么是模板匹配?

模板匹配是一种用于查找与模板图像(补丁)匹配(类似)的图像区域的技术。

虽然补丁必须是一个矩形,可能并不是所有的矩形都是相关的。在这种情况下,可以使用掩模来隔离应该用于找到匹配的补丁部分。

它是如何工作的?我们需要两个主要组件:源图像(I):我们期望找到与模板图像匹配的图像

模板图像(T):将与模板图像进行比较的补丁图像

我们的目标是检测最匹配的区域:

要识别匹配区域,我们必须通过滑动来比较模板图像与源图像:

通过滑动,我们的意思是一次移动补丁一个像素(从左到右,从上到下)。在每个位置,计算度量,以便它表示在该位置处的匹配的“好”还是“坏”(或者与图像的特定区域相似)。

对于T的每个位置超过I,则存储在该度量结果矩阵 R。R中的每个位置(x,y)都包含匹配度量

上面的图片是一个度量tm_ccorr_normed滑动补丁结果R。最亮的位置表示最高匹配。如您所见,红色圆圈标记的位置可能是具有最高值的位置,因此这个位置(由点形成的矩形,角度和宽度和高度等于补丁图像)被认为是匹配。实际上,我们使用函数minMaxLoc()定位R矩阵中最高的值(或更低的取决于匹配方法的类型)

mask是如何工作的?如果匹配需要屏蔽,则需要三个组件:源图像(I):我们期望找到与模板图像匹配的图像

模板图像(T):将与模板图像进行比较的补丁图像

掩模图像(M):The mask,屏蔽模板的灰度图像目前只有两种匹配方法接受掩码:CV_TM_SQDIFF和CV_TM_CCORR_NORMED(有关opencv中可用的所有匹配方法的说明,请参见下文)。

The mask必须与模板尺寸相同

The mask应具有CV_8U或CV_32F深度和与模板图像相同数量的通道。在CV_8U情况下,The mask值被视为二进制,即零和非零。在CV_32F情况下,值应该落在[0..1]范围内,并且模板像素将乘以相应的The mask像素值。由于样本中的输入图像具有CV_8UC3类型,因此屏蔽也被读取为彩色图像。

OpenCV中可以使用哪些匹配方法?

OpenCV在函数matchTemplate()中实现模板匹配。可用的方法有以上6种:method=CV_TM_SQDIFF

method=CV_TM_SQDIFF_NORMED

method=CV_TM_CCORR

method=CV_TM_CCORR_NORMED

method=CV_TM_CCOEFF

where

method=CV_TM_CCOEFF_NORMED

Code

C ++

这个程序是做什么的?加载输入图像,图像补丁(模板)和可选的mask

使用OpenCV函数matchTemplate()与之前描述的6种匹配方法中的任何一种执行模板匹配过程。用户可以通过在轨迹栏中输入其选择来选择该方法。如果提供了一个mask,它只会用于支持mask的方法

规范匹配过程的输出

以较高的匹配概率来定位位置

在与最高匹配相对应的区域周围绘制一个矩形可下载的代码:点击这里

代码一览:#include "opencv2/imgcodecs.hpp"

#include "opencv2/highgui.hpp"

#include "opencv2/imgproc.hpp"

#include

using namespace std;

using namespace cv;

bool use_mask;

Mat img; Mat templ; Mat mask; Mat result;

const char* image_window = "Source Image";

const char* result_window = "Result window";

int match_method;

int max_Trackbar = 5;

void MatchingMethod( int, void* );

int main( int argc, char** argv )

{

if (argc < 3)

{

cout << "Not enough parameters" << endl;

cout << "Usage:\n./MatchTemplate_Demo []" << endl;

return -1;

}

img = imread( argv[1], IMREAD_COLOR );

templ = imread( argv[2], IMREAD_COLOR );

if(argc > 3) {

use_mask = true;

mask = imread( argv[3], IMREAD_COLOR );

}

if(img.empty() || templ.empty() || (use_mask && mask.empty()))

{

cout << "Can't read one of the images" << endl;

return -1;

}

namedWindow( image_window, WINDOW_AUTOSIZE );

namedWindow( result_window, WINDOW_AUTOSIZE );

const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";

createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );

MatchingMethod( 0, 0 );

waitKey(0);

return 0;

}

void MatchingMethod( int, void* )

{

Mat img_display;

img.copyTo( img_display );

int result_cols = img.cols - templ.cols + 1;

int result_rows = img.rows - templ.rows + 1;

result.create( result_rows, result_cols, CV_32FC1 );

bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);

if (use_mask && method_accepts_mask)

{ matchTemplate( img, templ, result, match_method, mask); }

else

{ matchTemplate( img, templ, result, match_method); }

normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

double minVal; double maxVal; Point minLoc; Point maxLoc;

Point matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

if( match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED )

{ matchLoc = minLoc; }

else

{ matchLoc = maxLoc; }

rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

imshow( image_window, img_display );

imshow( result_window, result );

return;

}

代码说明声明一些全局变量,如图像,模板和结果矩阵,以及匹配方法和窗口名称:bool use_mask;

Mat img; Mat templ; Mat mask; Mat result;

const char* image_window = "Source Image";

const char* result_window = "Result window";

int match_method;

int max_Trackbar = 5;加载源图像,模板,可选地,如果匹配方法支持,则使用mask:img = imread( argv[1], IMREAD_COLOR );

templ = imread( argv[2], IMREAD_COLOR );

if(argc > 3) {

use_mask = true;

mask = imread( argv[3], IMREAD_COLOR );

}

if(img.empty() || templ.empty() || (use_mask && mask.empty()))

{

cout << "Can't read one of the images" << endl;

return -1;

}创建跟踪栏以输入要使用的匹配方法。当检测到更改时,调用回调函数。const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";

createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );我们来看看回调函数。首先,它创建源图像的副本:Mat img_display;

img.copyTo( img_display );执行模板匹配操作。的参数是自然输入图像我,模板T,结果ř和match_method(由给定的TrackBar),和任选的掩模图像中号。bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);

if (use_mask && method_accepts_mask)

{ matchTemplate( img, templ, result, match_method, mask); }

else

{ matchTemplate( img, templ, result, match_method); }我们对结果进行归一化:normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );我们使用minMaxLoc()定位结果矩阵R中的最小值和最大值。double minVal; double maxVal; Point minLoc; Point maxLoc;

Point matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() )对于前两种方法(TM_SQDIFF和MT_SQDIFF_NORMED),最佳匹配是最低值。对于所有其他的,更高的值表示更好的匹配。所以我们把对应的值保存在matchLoc变量中:if( match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED )

{ matchLoc = minLoc; }

else

{ matchLoc = maxLoc; }显示源图像和结果矩阵。在最高可能的匹配区域周围绘制一个矩形:rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

imshow( image_window, img_display );

imshow( result_window, result );

Java代码一览import org.opencv.core.*;

import org.opencv.core.Point;

import org.opencv.imgcodecs.Imgcodecs;

import org.opencv.imgproc.Imgproc;

import javax.swing.*;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.awt.image.DataBufferByte;

import java.util.*;

class MatchTemplateDemoRun implements ChangeListener{

Boolean use_mask = false;

Mat img = new Mat(), templ = new Mat();

Mat mask = new Mat();

int match_method;

JLabel imgDisplay = new JLabel(), resultDisplay = new JLabel();

public void run(String[] args) {

if (args.length < 2)

{

System.out.println("Not enough parameters");

System.out.println("Program arguments:\n []");

System.exit(-1);

}

img = Imgcodecs.imread( args[0], Imgcodecs.IMREAD_COLOR );

templ = Imgcodecs.imread( args[1], Imgcodecs.IMREAD_COLOR );

if(args.length > 2) {

use_mask = true;

mask = Imgcodecs.imread( args[2], Imgcodecs.IMREAD_COLOR );

}

if(img.empty() || templ.empty() || (use_mask && mask.empty()))

{

System.out.println("Can't read one of the images");

System.exit(-1);

}

matchingMethod();

createJFrame();

}

private void matchingMethod() {

Mat result = new Mat();

Mat img_display = new Mat();

img.copyTo( img_display );

int result_cols = img.cols() - templ.cols() + 1;

int result_rows = img.rows() - templ.rows() + 1;

result.create( result_rows, result_cols, CvType.CV_32FC1 );

Boolean method_accepts_mask = (Imgproc.TM_SQDIFF == match_method ||

match_method == Imgproc.TM_CCORR_NORMED);

if (use_mask && method_accepts_mask)

{ Imgproc.matchTemplate( img, templ, result, match_method, mask); }

else

{ Imgproc.matchTemplate( img, templ, result, match_method); }

Core.normalize( result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat() );

double minVal; double maxVal;

Point matchLoc;

Core.MinMaxLocResult mmr = Core.minMaxLoc( result );

// For all the other methods, the higher the better

if( match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED )

{ matchLoc = mmr.minLoc; }

else

{ matchLoc = mmr.maxLoc; }

Imgproc.rectangle(img_display, matchLoc, new Point(matchLoc.x + templ.cols(),

matchLoc.y + templ.rows()), new Scalar(0, 0, 0), 2, 8, 0);

Imgproc.rectangle(result, matchLoc, new Point(matchLoc.x + templ.cols(),

matchLoc.y + templ.rows()), new Scalar(0, 0, 0), 2, 8, 0);

Image tmpImg = toBufferedImage(img_display);

ImageIcon icon = new ImageIcon(tmpImg);

imgDisplay.setIcon(icon);

result.convertTo(result, CvType.CV_8UC1, 255.0);

tmpImg = toBufferedImage(result);

icon = new ImageIcon(tmpImg);

resultDisplay.setIcon(icon);

}

public void stateChanged(ChangeEvent e) {

JSlider source = (JSlider) e.getSource();

if (!source.getValueIsAdjusting()) {

match_method = (int)source.getValue();

matchingMethod();

}

}

public Image toBufferedImage(Mat m) {

int type = BufferedImage.TYPE_BYTE_GRAY;

if ( m.channels() > 1 ) {

type = BufferedImage.TYPE_3BYTE_BGR;

}

int bufferSize = m.channels()*m.cols()*m.rows();

byte [] b = new byte[bufferSize];

m.get(0,0,b); // get all the pixels

BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);

final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();

System.arraycopy(b, 0, targetPixels, 0, b.length);

return image;

}

private void createJFrame() {

String title = "Source image; Control; Result image";

JFrame frame = new JFrame(title);

frame.setLayout(new GridLayout(2, 2));

frame.add(imgDisplay);

int min = 0, max = 5;

JSlider slider = new JSlider(JSlider.VERTICAL, min, max, match_method);

slider.setPaintTicks(true);

slider.setPaintLabels(true);

// Set the spacing for the minor tick mark

slider.setMinorTickSpacing(1);

// Customizing the labels

Hashtable labelTable = new Hashtable();

labelTable.put( new Integer( 0 ), new JLabel("0 - SQDIFF") );

labelTable.put( new Integer( 1 ), new JLabel("1 - SQDIFF NORMED") );

labelTable.put( new Integer( 2 ), new JLabel("2 - TM CCORR") );

labelTable.put( new Integer( 3 ), new JLabel("3 - TM CCORR NORMED") );

labelTable.put( new Integer( 4 ), new JLabel("4 - TM COEFF") );

labelTable.put( new Integer( 5 ), new JLabel("5 - TM COEFF NORMED : (Method)") );

slider.setLabelTable( labelTable );

slider.addChangeListener(this);

frame.add(slider);

frame.add(resultDisplay);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setVisible(true);

}

}

public class MatchTemplateDemo

{

public static void main(String[] args) {

// load the native OpenCV library

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

// run code

new MatchTemplateDemoRun().run(args);

}

}

代码说明

代码说明声明一些全局变量,如图像,模板和结果矩阵,以及匹配方法和窗口名称:Boolean use_mask = false;

Mat img = new Mat(), templ = new Mat();

Mat mask = new Mat();

int match_method;

JLabel imgDisplay = new JLabel(), resultDisplay = new JLabel();加载源图像,模板,可选地,如果匹配方法支持,则使用mask:img = Imgcodecs.imread( args[0], Imgcodecs.IMREAD_COLOR );

templ = Imgcodecs.imread( args[1], Imgcodecs.IMREAD_COLOR );创建跟踪栏以输入要使用的匹配方法。当检测到更改时,调用回调函数。int min = 0, max = 5;

JSlider slider = new JSlider(JSlider.VERTICAL, min, max, match_method);我们来看看回调函数。首先,它创建源图像的副本:Mat img_display = new Mat();

img.copyTo( img_display );执行模板匹配操作。的参数是自然输入图像我,模板T,结果ř和match_method(由给定的TrackBar),和任选的掩模图像中号。Boolean method_accepts_mask = (Imgproc.TM_SQDIFF == match_method ||

match_method == Imgproc.TM_CCORR_NORMED);

if (use_mask && method_accepts_mask)

{ Imgproc.matchTemplate( img, templ, result, match_method, mask); }

else

{ Imgproc.matchTemplate( img, templ, result, match_method); }我们对结果进行归一化:Core.normalize( result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat() );我们使用minMaxLoc()定位结果矩阵R中的最小值和最大值。double minVal; double maxVal;

Point matchLoc;

Core.MinMaxLocResult mmr = Core.minMaxLoc( result );对于前两种方法(TM_SQDIFF和MT_SQDIFF_NORMED),最佳匹配是最低值。对于所有其他的,更高的值表示更好的匹配。所以我们把对应的值保存在matchLoc变量中:// For all the other methods, the higher the better

if( match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED )

{ matchLoc = mmr.minLoc; }

else

{ matchLoc = mmr.maxLoc; }显示源图像和结果矩阵。在最高可能的匹配区域周围绘制一个矩形:Imgproc.rectangle(img_display, matchLoc, new Point(matchLoc.x + templ.cols(),

matchLoc.y + templ.rows()), new Scalar(0, 0, 0), 2, 8, 0);

Imgproc.rectangle(result, matchLoc, new Point(matchLoc.x + templ.cols(),

matchLoc.y + templ.rows()), new Scalar(0, 0, 0), 2, 8, 0);

Image tmpImg = toBufferedImage(img_display);

ImageIcon icon = new ImageIcon(tmpImg);

imgDisplay.setIcon(icon);

result.convertTo(result, CvType.CV_8UC1, 255.0);

tmpImg = toBufferedImage(result);

icon = new ImageIcon(tmpImg);

resultDisplay.setIcon(icon);

Python代码一览import sys

import cv2

use_mask = False

img = None

templ = None

mask = None

image_window = "Source Image"

result_window = "Result window"

match_method = 0

max_Trackbar = 5

def main(argv):

if (len(sys.argv) < 3):

print 'Not enough parameters'

print 'Usage:\nmatch_template_demo.py []'

return -1

global img

global templ

img = cv2.imread(sys.argv[1], cv2.IMREAD_COLOR)

templ = cv2.imread(sys.argv[2], cv2.IMREAD_COLOR)

if (len(sys.argv) > 3):

global use_mask

use_mask = True

global mask

mask = cv2.imread( sys.argv[3], cv2.IMREAD_COLOR )

if ((img is None) or (templ is None) or (use_mask and (mask is None))):

print 'Can\'t read one of the images'

return -1

cv2.namedWindow( image_window, cv2.WINDOW_AUTOSIZE )

cv2.namedWindow( result_window, cv2.WINDOW_AUTOSIZE )

trackbar_label = 'Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED'

cv2.createTrackbar( trackbar_label, image_window, match_method, max_Trackbar, MatchingMethod )

MatchingMethod(match_method)

cv2.waitKey(0)

return 0

def MatchingMethod(param):

global match_method

match_method = param

img_display = img.copy()

method_accepts_mask = (cv2.TM_SQDIFF == match_method or match_method == cv2.TM_CCORR_NORMED)

if (use_mask and method_accepts_mask):

result = cv2.matchTemplate(img, templ, match_method, None, mask)

else:

result = cv2.matchTemplate(img, templ, match_method)

cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 )

_minVal, _maxVal, minLoc, maxLoc = cv2.minMaxLoc(result, None)

if (match_method == cv2.TM_SQDIFF or match_method == cv2.TM_SQDIFF_NORMED):

matchLoc = minLoc

else:

matchLoc = maxLoc

cv2.rectangle(img_display, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,0), 2, 8, 0 )

cv2.rectangle(result, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,0), 2, 8, 0 )

cv2.imshow(image_window, img_display)

cv2.imshow(result_window, result)

pass

if __name__ == "__main__":

main(sys.argv[1:])

代码说明声明一些全局变量,如图像,模板和结果矩阵,以及匹配方法和窗口名称:use_mask = False

img = None

templ = None

mask = None

image_window = "Source Image"

result_window = "Result window"

match_method = 0

max_Trackbar = 5加载源图像,模板,可选地,如果匹配方法支持,则使用mask:global img

global templ

img = cv2.imread(sys.argv[1], cv2.IMREAD_COLOR)

templ = cv2.imread(sys.argv[2], cv2.IMREAD_COLOR)

if (len(sys.argv) > 3):

global use_mask

use_mask = True

global mask

mask = cv2.imread( sys.argv[3], cv2.IMREAD_COLOR )

if ((img is None) or (templ is None) or (use_mask and (mask is None))):

print 'Can\'t read one of the images'

return -1创建跟踪栏以输入要使用的匹配方法。当检测到更改时,调用回调函数。trackbar_label = 'Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED'

cv2.createTrackbar( trackbar_label, image_window, match_method, max_Trackbar, MatchingMethod )我们来看看回调函数。首先,它创建源图像的副本:img_display = img.copy()执行模板匹配操作。的参数是自然输入图像我,模板T,结果ř和match_method(由给定的TrackBar),和任选的掩模图像中号。method_accepts_mask = (cv2.TM_SQDIFF == match_method or match_method == cv2.TM_CCORR_NORMED)

if (use_mask and method_accepts_mask):

result = cv2.matchTemplate(img, templ, match_method, None, mask)

else:

result = cv2.matchTemplate(img, templ, match_method)我们对结果进行归一化:cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 )我们使用minMaxLoc()定位结果矩阵R中的最小值和最大值。_minVal, _maxVal, minLoc, maxLoc = cv2.minMaxLoc(result, None)对于前两种方法(TM_SQDIFF和MT_SQDIFF_NORMED),最佳匹配是最低值。对于所有其他的,更高的值表示更好的匹配。所以我们把对应的值保存在matchLoc变量中:if (match_method == cv2.TM_SQDIFF or match_method == cv2.TM_SQDIFF_NORMED):

matchLoc = minLoc

else:

matchLoc = maxLoc显示源图像和结果矩阵。在最高可能的匹配区域周围绘制一个矩形:cv2.rectangle(img_display, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,0), 2, 8, 0 )

cv2.rectangle(result, matchLoc, (matchLoc[0] + templ.shape[0], matchLoc[1] + templ.shape[1]), (0,0,0), 2, 8, 0 )

cv2.imshow(image_window, img_display)

cv2.imshow(result_window, result)

结果使用输入图像测试我们的程序,如:

和模板图片:

生成以下结果矩阵(第一行是标准方法SQDIFF,CCORR和CCOEFF,第二行在其标准化版本中是相同的方法)。在第一列中,最黑暗的是更好的匹配,对于另外两列,位置越亮,匹配越高。

RESULT_0

Result_1

Result_2

Result_3

Result_4

Result_5

正确的匹配如下所示(黑色矩形在右边的家伙的脸上)。请注意,CCORR和CCDEFF给出了错误的最佳匹配,但是它们的正常版本是正确的,这可能是因为我们只考虑“最高匹配”,而不是其他可能的高匹配。

java通过模板匹配html,OpenCV模板匹配相关推荐

  1. Java + OpenCV 模板匹配

    何为模板匹配 模板匹配就是在指定模板图片中,在模板区域内找寻与待匹配图片中最相似的.通过不断滑动模板图片,计算其与待匹配图片区域的匹配度,将匹配度最高区域视为最终匹配结果. 实现方法 Imgproc. ...

  2. OpenCV模板匹配Template Matching

    OpenCV模板匹配Template Matching 模板匹配Template Matching 目标 理论 什么是模板匹配? OpenCV提供哪些匹配方法? 代码 解释 结果 模板匹配Templa ...

  3. 图像匹配与OpenCV模板匹配

    介绍 (Introduction) As a data scientist at VATBox, I've mainly worked on projects which at their core ...

  4. opencv 模板匹配(cvMatchTemplate)

    opencv 模板匹配(cvMatchTemplate) 模板匹配是通过在输入图像上滑动模板图像块对实际的图像块和输入图像进行匹配,并且可以利用函数cvMinMaxLoc()找到最佳匹配的位置.例如在 ...

  5. opencv 模板匹配_详细剖析模板匹配

    点击上方"新机器视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 模板匹配介绍 我们需要2幅图像: 原图像 (I): 在这幅图像里, ...

  6. OpenCV模板匹配函数:matchTemplate()介绍

    OpenCV模板匹配函数:matchTemplate()介绍

  7. opencv 模板匹配,在图像中寻找物体

    使用模板匹配在图像中寻找物体 模板匹配 模板匹配就是用来在大图中找小图,也就是说在一副图像中寻找另外一张模板图像的位置: opencv中用 cv.matchTemplate() 实现模板匹配. 模板匹 ...

  8. OpenCV—python 模板匹配与图像特征匹配

    文章目录 一.理论介绍与算法 二.算法代码 单目标匹配 多目标匹配 三 多尺度模板匹配 一.理论介绍与算法 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个 ...

  9. OpenCV模板匹配识别图片中的数字

    OpenCV模板匹配识别图片中的数字 前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作 ...

最新文章

  1. piwik的安装与配置
  2. V$LICENSE表结构
  3. js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME) 转载...
  4. OpenCV编程-无法解析的外部符号 void __cdecl cv::cvtColor
  5. 转【28个Unix/Linux的命令行神器-----陈皓】
  6. JAVA获取word书签内容_java操作word可操作书签
  7. oracle客户端 PLSQL安装配置教程
  8. java: 找不到符号 报错
  9. Bugku -disordered_zip【MISC】
  10. 计算机桌面个性化怎样设置方法,终于知晓如何设置个性化电脑桌面?
  11. 联想用u盘重装系统步骤_用u盘给联想笔记本装系统
  12. 关于环信客服的集成与使用
  13. 游泳池 (Standard IO)
  14. 项目介绍之论文格式的自动检测与修改系统
  15. 2020年11月 工信部考试——Hadoop(数据应用技术)中级认证 1
  16. 开发者能力大赏,谁是技术知识达人?
  17. there is no statement named xxx in this SqlMap
  18. PNG图片怎么将图片大小压缩
  19. 遇到《顺丰速运》app奔溃了,怎么回事呢?
  20. Altium Designer 超详细学习教程——前言

热门文章

  1. 03-基于树莓派4B和西门子SM1281的FTP传输实现
  2. 【基操】添加环境变量
  3. pc端react预览图片的两款插件,react-images, react-images-viewer
  4. 【23年1月17日】基于Flask技术的全国气象数据采集及可视化分析系统,支持城市定制服务
  5. 蓝松短视频SDK, 更新日志
  6. qnx环境下编译ffmpeg及解码mp4实践
  7. Studio One 5使用FX辅助音轨发送混响没有效果(已解决)
  8. C++数据库编程 ODBC插入数据
  9. 虚拟化正成为主流IT运营方式
  10. pyecharts常见柱状图、圆饼图、散点图