我在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);
我期待它以白色覆盖整个图像,但图像的下半部分仍然是空的。如果我这样做的话
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);
整个图像均以白色覆盖。所以,这意味着src.at(i,j)使用(i,j)作为(行,列),但Point(x,y)使用(x,y)作为(列,行)
答案 0 :(得分:80)
所以,这意味着src.at(i,j)使用(i,j)作为(行,列),但Point(x,y)使用(x,y)作为(列,行)< / p>
这是对的!由于这似乎让很多人感到困惑,我会写下我的解释原因:
在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
2. 对于点,选择的坐标系统可以完成两件事: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--->
但是因为我们希望将左上角和正值的原点转到底部,而是:
0/0---X--->
|
|
Y
|
|
v
因此,对于图像处理,人行首先表示法可能很奇怪,但对于数学家来说,x轴 - 首先访问矩阵会很奇怪。
因此,在OpenCV中,您可以使用:mat.at<type>(row,column)
或mat.at<type>(cv::Point(x,y))
来访问同一点x=column
和y=row
,这是完全可理解的=)
希望这是正确的。我对这些符号知之甚少,但这就是我在数学和成像方面的经验告诉我的。
答案 1 :(得分:2)
我通过在第四象限中将坐标从opencv转换为笛卡尔坐标,只需在y坐标前面放置一个( - )ve符号即可快速快速地解决这个问题。
通过这种方式,我能够使用我现有的算法和所有标准的笛卡尔系统方程式与opencv,而不会在坐标系之间进行昂贵的转换,从而在系统上增加很多开销。
0/0---X--->
|
|
Y
|
|
v
(opencv)
0/0---X---->
|
|
|
-Y
|
|
v
(4th quadrant)
答案 2 :(得分:0)
这是一个直观的示例,可将python的[行,列]与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 # inver x and y
plt.figure()
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]")
这将输出:
答案 3 :(得分:0)
按照惯例,指向 OpenCV 后跟 (x, y)。在计算机屏幕上,x 是按列排列的,而 y 是按行排列的。这是使用内置 circle
函数的示例。
win_name = "Test"
image_width, image_height = 300, 200
center_x, center_y = 300, 0
circle_radius = 9
# Create a black image
img = np.zeros((image_height, image_width, 3), np.uint8)
# BGR
cv2.circle(img, center=tuple([center_x, center_y]),
radius=circle_radius, color=(255,0,0),
thickness=-1)
# Open openCV window
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)
cv2.resizeWindow(win_name, image_width, image_height)
cv2.moveWindow(win_name, 120, 850)
cv2.setWindowTitle(win_name, win_name)
cv2.imshow(win_name, img)
k = cv2.waitKey(0)
顺便说一下,它们在制作图像时遵循高度和宽度顺序,并且 BGR 颜色格式不是 RGB。这与传统相反。