我一直在用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)
答案 0 :(得分:4)
C ++代码需要重做:goto
语句和索引增加等效于continue
指令(在C /中,您几乎 几乎不需要goto
C ++程序,并且肯定不在这里,是原始的C ++代码,其“模拟” 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的另一个问题是,如果特殊情况发生在数组的末尾,那么您可以在数组的边界之外读取:未定义的行为)
现在,您可以直接在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
循环都控制迭代。您只需告诉python使用continue
跳到下一个迭代,就像在“新” C ++代码中一样。
答案 1 :(得分:0)
由于所有跳转似乎都由j ++进行,并且跳转是循环的开始,因此Python继续语句似乎很容易解决您的问题?
# 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)
...
答案 2 :(得分:0)
好的。 我建议这个。
public class MyWindow : Window
{
public MyWindow()
{
DetectForTabletMode();
// Turn OFF auto-rotation for duration of my primary application window
MyUser32.SetAutoRotation(false);
// Hooks for detecting screen bounds / taskbar height impact to form
// the "SystemEvents" is a static instance and always available. I have added
// so each window can adjust itself as needed. I have actually hooked into
// both User preferences and Display Settings
SystemEvents.UserPreferenceChanged += MyWindow_DisplaySettingsChanged;
SystemEvents.DisplaySettingsChanged += MyWindow_DisplaySettingsChanged;
// hook to closed event so I can clean up when window is finished
Closed += MyWindow_Closed;
}
private void MyWindow_Closed(object sender, EventArgs e)
{
// Disconnect event handler for detecting when in/out of tablet mode
if(_tabletWatch != null )
{
_tabletWatch.EventArrived -= tabletWatch_EventArrived;
_tabletWatch.Stop();
}
// When closing my main window, re-enable the auto-rotation
MyUser32.SetAutoRotation(true);
// Disable screen resolution impact to prevent memory leaks
// must release on closing window or memory leaks per MS documentation
// https://docs.microsoft.com/en-us/dotnet/api/microsoft.win32.systemevents.displaysettingschanged?view=netframework-4.7.2
SystemEvents.UserPreferenceChanged -= MyWindow_DisplaySettingsChanged;
SystemEvents.DisplaySettingsChanged -= MyWindow_DisplaySettingsChanged;
// under your control, probably only want to turn back on at the END of the APPLICATION
// and not just all windows individually
MyUser32.SetAutoRotation(true);
}
#region Detect / Set / Handle tablet mode
private bool _inTabletMode;
public bool InTabletMode
{
get { return _inTabletMode; }
private set
{
_inTabletMode = value;
// do anything you want when changing in/out of tablet mode
}
}
private ManagementEventWatcher _tabletWatch;
private void DetectForTabletMode()
{
var currentUser = WindowsIdentity.GetCurrent();
// to capture event when user swaps between normal and tablet modes.
if (currentUser != null && currentUser.User != null)
{
var wqlEventQuery = new EventQuery( string.Format(
@"SELECT *
FROM
RegistryValueChangeEvent
WHERE
Hive='HKEY_USERS'
AND KeyPath='{0}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell'
AND ValueName='TabletMode'", currentUser.User.Value ));
_tabletWatch = new ManagementEventWatcher(wqlEventQuery);
_tabletWatch.EventArrived += tabletWatch_EventArrived;
_tabletWatch.Start();
}
}
private void tabletWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
Dispatcher.Invoke(() =>
{
InTabletMode = 1 == (int)Registry.GetValue("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ImmersiveShell", "TabletMode", 0);
});
}
#endregion Detect / Set / Handle tablet mode
#region Display and Orientation settings
private System.Drawing.Rectangle _lastDimensions;
// typical mode is landscape such as desktop / notbook mode anyhow.
private bool _isLandscapeMode = true;
public bool IsLandscapeMode { get { return _isLandscapeMode; } }
private bool _isPortraitMode { get { return !_isLandscapeMode; } }
public bool IsPortraitMode { get { return _isPortraitMode; } }
private void MyWindow_DisplaySettingsChanged(object sender, EventArgs e)
{
// get WINDOWS primary screen boundary dimensions
var psb = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
// only if coming in and different than a previous setting
if (_lastDimensions != null)
{
// Compare height and width of screen and act accordingly for orientation
_isLandscapeMode = (psb.Height < psb.Width);
// did dimensions change, such as from height of taskbar area shrinking
// available real estate for YOUR Window.
if (_lastDimensions.Height == psb.Height
&& _lastDimensions.Width == psb.Width)
// same dimensions, get out, nothing more to do...
return;
// allow virtual method per form to handle itself as needed
// and pass in the new dimensions.
WinDimensionsChanged(psb);
}
// always preserve latest dimensions IN-CASE changes, such as taskbar, etc..
_lastDimensions = psb;
}
protected virtual void WinDimensionsChanged(System.Drawing.Rectangle newestDimensions)
{
// do whatever you want per child-declared window
}
#endregion Display and Orientation settings
}
由于我不了解其余代码,因此我不太准确。 请告诉我是否发生任何错误。