我在Matrix src中有300*200的图像.我正在对图像进行以下操作.
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
line( src, Point(i,j),Point(i,j), Scalar( 255, 0, 0 ), 1,8 );
}
]
imshow("A",src);
waitKey(0);
Run Code Online (Sandbox Code Playgroud)
我期待它以白色覆盖整个图像,但图像的下半部分仍然是空的.如果我这样做的话
for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
src.at<uchar>(i,j)=255;
}
]
imshow("A",src);
waitKey(0);
Run Code Online (Sandbox Code Playgroud)
整个图像覆盖白色.所以,这意味着src.at(i,j)使用(i,j)作为(行,列),但Point(x,y)使用(x,y)作为(列,行)
Mic*_*cka 88
所以,这意味着src.at(i,j)使用(i,j)作为(行,列),但Point(x,y)使用(x,y)作为(列,行)
那是对的!由于这似乎让很多人感到困惑,我会写下我的解释,原因如下:
在OpenCV中,cv::Mat用于图像和矩阵,因为离散图像基本上与矩阵相同.
在数学中,我们有一些不同的东西:
1.对于矩阵的数学表示法是以行优先次序是订购
按照传统的矩阵表示法,行由二维数组的第一个索引编号,列由第二个索引编号,即a1,2是第一行的第二个元素,向下和向右计数.(注意这与笛卡尔惯例相反.)
摘自http://en.wikipedia.org/wiki/Row-major_order#Explanation_and_example
与数学一样,row:0,column:0是矩阵的左上角元素.行/列就像表格一样......
0/0---column--->
|
|
row
|
|
v
Run Code Online (Sandbox Code Playgroud)
2.对于Points,选择一个坐标系来完成两件事:1.它使用与矩阵表示法相同的单位大小和相同的"原点",因此左上角是Point(0,0),轴长度1表示1行或1列的长度.2.它使用"图像符号"进行轴排序,这意味着横坐标(横轴)是指定x方向的第一个值,纵坐标(纵轴)是指定y方向的第二个值.
轴相交的点是两条数字线的共同原点,简称为原点.它通常标记为O,如果是,那么轴称为Ox和Oy.定义了x轴和y轴的平面通常称为笛卡尔平面或xy平面.x的值称为x坐标或横坐标,y的值称为y坐标或纵坐标.
字母的选择来自原始约定,即使用字母表的后半部分来表示未知值.字母表的第一部分用于指定已知值.
http://en.wikipedia.org/wiki/Cartesian_coordinate_system#Two_dimensions
所以在一个完美的世界里,我们会选择点/图像的坐标系:
^
|
|
Y
|
|
0/0---X--->
Run Code Online (Sandbox Code Playgroud)
但由于我们希望将左上角和正值的原点转到底部,而是:
0/0---X--->
|
|
Y
|
|
v
Run Code Online (Sandbox Code Playgroud)
因此对于图像处理,人行首先表示法可能很奇怪,但对于数学家来说,x轴 - 首先访问矩阵会很奇怪.
所以在OpenCV中,你可以使用:mat.at<type>(row,column)或者mat.at<type>(cv::Point(x,y))访问如果相同点x=column和y=row这是完全可以理解=)
希望这是正确的.我对这些符号知之甚少,但这就是我在数学和成像方面的经验告诉我的.
这是一个区分 python 的 [row, columns] 和 OpenCV 的 [x,y] 的直观示例。
import numpy as np
import matplotlib.pyplot as plt
import cv2
img = np.zeros((5,5)) # initialize empty image as numpy array
img[0,2] = 1 # assign 1 to the pixel of row 0 and column 2
M = cv2.moments(img) # calculate moments of binary image
cX = int(M["m10"] / M["m00"]) # calculate x coordinate of centroid
cY = int(M["m01"] / M["m00"]) # calculate y coordinate of centroid
img2 = np.zeros((5,5)) # initialize another empty image
img2[cX,cY] = 1 # assign 1 to the pixel with x = cX and y = cY
img3 = np.zeros((5,5)) # initialize another empty image
img3[cY,cX] = 1 # invert x and y
plt.figure()
plt.subplots_adjust(wspace=0.4) # add space between subplots
plt.subplot(131), plt.imshow(img, cmap = "gray"), plt.title("With [rows,cols]")
plt.subplot(132), plt.imshow(img2, cmap = "gray"), plt.title("With [x,y]")
plt.subplot(133), plt.imshow(img3, cmap= "gray"), plt.title("With [y,x]"), plt.xlabel('x'), plt.ylabel('y')
Run Code Online (Sandbox Code Playgroud)
这将输出:
I found a quick and fast fix to this problem by just converting the coordinates from opencv to Cartesian coordinates in 4th quadrant, simply by putting a (-)ve sign in front of the y coordinate.
通过这种方式,我能够在 opencv 中使用我现有的算法和所有标准笛卡尔系统方程,而不会通过在坐标系之间进行昂贵的转换而给系统带来太多开销。
0/0---X--->
|
|
Y
|
|
v
(opencv)
0/0---X---->
|
|
|
-Y
|
|
v
(4th quadrant)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54923 次 |
| 最近记录: |