使用 goto 语句对 C++ 块进行 Python 化处理

Pythonizing C++ block with goto statement

我一直在 Python 编写 C++ 代码,但遇到了一种让我有点卡住的情况。程序员使用 goto 语句来实现他的逻辑,并且由于 Python 中没有 goto 语句,并且由于我不想深入研究它的有趣 goto 实现,我想知道我们是否可以某种方式 Python对以下块进行处理:

// Loop over all detected circles of the input image
    for (int j = 0; j < circle_radius_vec.size(); ++j)
    {   
        Jump: 

        // Variables for ROI
        int roi_height_width = 0;
        int roi_corner_x = 0;
        int roi_corner_y = 0;

        Point center_now(roi_height_width/2, roi_height_width/2);

        // Load aktuellen center point
        center_now = center_vec[j];

        // Calculate ROI 
        roi_height_width = circle_radius_vec[j];
        roi_corner_x = center_now.x - roi_height_width/2;
        roi_corner_y = center_now.y - roi_height_width/2;   

        // If ROI is outside of image skip circle
        if(roi_corner_x < 0){j++; goto Jump;}
        if(roi_corner_y < 0){j++; goto Jump;}
        if((roi_corner_x+roi_height_width) > input_img.cols){j++; goto Jump;}
        if((roi_corner_y+roi_height_width) > input_img.rows){j++; goto Jump;}

        // Create ROI from input image
        Rect roi = Rect(roi_corner_x, roi_corner_y, roi_height_width, roi_height_width);
        Mat img_roi = input_img(roi);

        // Create HSV representation of ROI
        Mat hsv;
        cvtColor(img_roi, hsv, COLOR_BGR2HSV);
        ...

他有一个名为 "Jump" 的标签,他要去那里。我们如何 Python 处理这个?由于我们已经处于for循环中,我有点犹豫是否要引入更多循环。

提前致谢。

编辑:感谢贡献者,提出了以下建议,但是这陷入了无限循环:

# Loop over all detected circles of the input image
    for j in range(len(center_vec)):
        while True:
            # arrange the ROI
            # load the current center point
            center_now = center_vec[j] # take the center of ROI as the center of circle
            roi_height_width = int(round(circle_radius_vec[j])) # take the radius as height and width of the ROI
            roi_height_width = int(round(circle_radius_vec[j]))

            roi_corner_x = int(round(center_now[0] - roi_height_width / 2))
            roi_corner_y = int(round(center_now[1] - roi_height_width / 2))

            # If ROI is outside of image skip circle
            if roi_corner_x < 0:
                j += 1
                continue
            if roi_corner_y < 0:
                j += 1
                continue
            if roi_corner_x + roi_height_width > img.shape[1]:
                j += 1
                continue
            if roi_corner_y + roi_height_width > img.shape[0]:
                j += 1
                continue

        # create ROI from input image Rect
        roi = img[roi_corner_y:roi_corner_y+roi_height_width, roi_corner_x:roi_corner_x+roi_height_width]

        # Create HSV representation of ROI
        hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)

因为所有的跳转似乎都在 j++ 之前并且跳转是循环的开始,所以 Python continue 语句似乎很容易解决您的问题?

# Loop over all detected circles of the input image
for in range(1, circle_radius_vec.size()):

    # Variables for ROI
    roi_height_width = 0
    roi_corner_x = 0
    roi_corner_y = 0

    Point center_now(roi_height_width/2, roi_height_width/2)

    # Load aktuellen center point
    center_now = center_vec[j]

    # Calculate ROI 
    roi_height_width = circle_radius_vec[j]
    roi_corner_x = center_now.x - roi_height_width/2
    roi_corner_y = center_now.y - roi_height_width/2   

    # If ROI is outside of image skip circle
    if roi_corner_x < 0 or roi_corner_y < 0 or roi_corner_x + roi_height_width > input_img.cols or roi_corner_y + roi_height_width > input_img.rows:
        continue

    # Create ROI from input image
    Rect roi = Rect(roi_corner_x, roi_corner_y, roi_height_width, roi_height_width)
    img_roi = input_img(roi)

    # Create HSV representation of ROI
    hsv()
    cvtColor(img_roi, hsv, COLOR_BGR2HSV)
    ...

我个人只是反转 if 语句并有条件地执行代码的下半部分,如下所示:

# Loop over all detected circles of the input image
for in range(1, circle_radius_vec.size()):

    # Variables for ROI
    roi_height_width = 0
    roi_corner_x = 0
    roi_corner_y = 0

    Point center_now(roi_height_width/2, roi_height_width/2)

    # Load aktuellen center point
    center_now = center_vec[j]

    # Calculate ROI 
    roi_height_width = circle_radius_vec[j]
    roi_corner_x = center_now.x - roi_height_width/2
    roi_corner_y = center_now.y - roi_height_width/2   

    # If ROI is outside of image skip circle
    if roi_corner_x >= 0 and roi_corner_y >= 0 and roi_corner_x + roi_height_width <= input_img.cols and roi_corner_y + roi_height_width <= input_img.rows:


        # Create ROI from input image
        Rect roi = Rect(roi_corner_x, roi_corner_y, roi_height_width, roi_height_width)
        img_roi = input_img(roi)

        # Create HSV representation of ROI
        hsv()
        cvtColor(img_roi, hsv, COLOR_BGR2HSV)
        ...

C++ 代码需要返工:goto 语句和索引增加等同于 continue 指令(你几乎从不 需要goto 在 C/C++ 程序中,绝对不在这里,原始 C++ 代码是 "emulating" continue 因为作者不知道它存在):

for (int j = 0; j < circle_radius_vec.size(); ++j)
    {   
        ..
        // If ROI is outside of image skip circle
        if(roi_corner_x < 0){continue;}

请注意,现在您不需要手动增加索引,因为 continue 会跳到下一次迭代,调用循环的 ++j

(incrementation+goto 的另一个问题是,如果特殊情况发生在数组的末尾,那么你可以在数组的边界之外读取:undefined behavior)

现在,您可以直接在 python 中转置它:您有 2 个选项:

要么使用索引(就像您的 C++ 代码那样)

for index in range(size):        
    ...
    if some_condition:
        continue

或者只是迭代元素(更多pythonic,因为它不使用索引):

for a in the_list:
    # a is the current element of the list, not the index
    ...
    if some_condition:
        continue

在这两种情况下,for 循环控制迭代。您只需使用 continue 告诉 python 跳到下一次迭代,就像在 "new" C++ 代码中一样。

当然可以。 我建议这样做。

# Loop over all detected circles ot the input image.
for j in range(len(circle_radius_vec)):
    # Variables for ROI.
    roi_height_width = 0
    roi_corner_x = 0
    roi_corner_y = 0

    # Calculate ROI 
    roi_height_width = circle_radius_vec[j]
    roi_corner_x = center_now.x - roi_height_width/2
    roi_corner_y = center_now.y - roi_height_width/2

    center_now = Point(roi_height_width/2, roi_height_width/2)

    # Load aktuellen center point.
    center_now = center_vec[j]

    # Calculate ROI.
    if roi_corner_x < 0:
        continue
    if roi_corner_y < 0:
        continue
    if roi_corner_x + roi_height_width > input_img.cols:
        continue


    # Create ROI from input image.
    roi = Rect(roi_corner_x, roi_corner_y, roi_height_width, roi_height_width)
    img_roi = input_img(roi)

    # Create HSV representation of ROI.
    hsv = None
    cvtColor(img_roi, hsv, COLOR_BGR2HSV)

因为我不知道其余的代码,所以我不能说得很准确。 如果有任何错误,请告诉我。